home *** CD-ROM | disk | FTP | other *** search
-
- /* C O P Y R I G H T N O T I C E : */
- /* Copyright 1986 Eric Jul and Norm Hutchinson. May not be used for any */
- /* purpose without written permission from the authors. */
-
- /* This source module contains the stuff to dynamically load an object */
- /* from a Ultrix file or from another kernel. */
-
- #include <stdio.h>
-
- #include "Kernel/h/system.h"
- #include "Kernel/h/macros.h"
- #include "Kernel/h/assert.h"
- #include <setjmp.h>
- #include <sys/file.h>
- #include <errno.h>
- #include <sys/time.h>
- #include <sys/stat.h>
-
- #include "Kernel/h/errMsgs.h"
- #include "Kernel/h/hotsTypes.h"
- #include "Kernel/h/ecTypes.h"
- #include "Kernel/h/emTypes.h"
- #include "Kernel/h/kmdTypes.h"
- #include "Kernel/h/lmTypes.h"
- #include "Kernel/h/kEvents.h"
- #include "Kernel/h/emkDefs.h"
- #include "Kernel/h/lmCodes.h"
- #include "Kernel/h/emCodes.h"
- #include "Kernel/h/map.h"
- #include "Kernel/h/map96.h"
- #include "Kernel/h/sigio.h"
- #include "Kernel/h/emeraldTypes.h"
- #include "Kernel/h/consts.h"
- #include "Kernel/h/builtins.h"
- #include "Kernel/h/utils.h"
-
- extern ODTag stdCodeODTag, stdDotoODTag, stdAbConTag;
- extern DotoFilePtr readDotoFile();
- extern void translateDoto(), retranslate();
- extern SSPtr NewProcess(), preemptRunning();
- extern void unavail(), fail(), schedule(), StartLocate();
- extern ODP OTLookup();
- extern void StartProcessAtAddr(), OTInsert();
- extern OID getNextOID();
- extern GODP AllocateWithOID(), MakeObject();
- extern char *PPSSPlace(), *PPPOID(), *PPGOID(), *PPFindLineNo(),
- *PPOID(), *PPCOID(), *PPCodePtr();
- extern CodeODP CreateCodeODEntry();
- extern GODP CreateGODEntry();
- extern char EMDIR[];
- extern EmLocation thisNodeLocation;
- extern GODP kernelStdInStream;
- extern GODP kernelStdOutStream;
- extern void DoCallBack();
- extern void UnblockInitially();
- extern void MakeStreamsFromSock();
-
-
- /* Global variables */
- Map CodeLoadMap;
- Map CompilerLoadMap;
- Map CheatingLoadMap;
- Map RemoteLoadMap;
-
- /*
- * UnknownATAbConMap maps ATOIDs into Sets.
- * Every ATOID for which the AT is not resident (i.e., the CodePtr is NULL)
- * there is a set of CTOIDs. For every one of these CTOIDs there
- * is an abcon with the ATOID and the CTOID.
- * This AbCon, when it was created, had to be faked since the AT was not
- * present (the CT might not be present either).
- * When a previously non-resident AT arrives, this Map must be checked
- * so that the faked AbCons can be fixed.
- * After fixing the AbCons, the entry should be removed.
- * If the CT is still missing then do not worry. The abcon will
- * get fixed when the CT arrives (the CT has a AbConSetPtr for this
- * purpose).
- *
- */
-
- Map UnknownATAbConMap;
-
- /*
- * AbConMap96 is a map of (AT, restrictAT, CT) -> AbConPtr.
- */
-
- Map96 AbConMap96;
- #define INITIALABCONMAP96SIZE 2048
- /*
- * vFLRemoteLoadDeamonInterval is the time that the Remote Load Deamon
- * waits before sending out remote load requests.
- * The idea is to batch the requests together, if possible.
- * In the common case, EnsurePresenceOfRequired types generates multiple
- * request and these will all be satified from the same remote node.
- */
-
- Boolean RemoteLoadDeamonRunning = FALSE;
- #define REMOTELOADDEAMONINTERVAL 20000 /* microseconds */
- int vFLRemoteLoadDeamonInterval=REMOTELOADDEAMONINTERVAL;
-
- #define MAXSOCK 32
- CompilerLoadReqPtr CReq[MAXSOCK];
-
- /* Local variables */
-
- jmp_buf errorExitPoint;
- int CompilerSock;
- struct sockaddr_in
- compilerSocket = {AF_INET}; /* Socket for compiler requests */
-
-
- #define MAXDOTOFILES 1000
-
- /* Forward */ void ReadCompilerRequest();
- /* Forward */ Boolean LoadRequest();
- /* Forward */ void CloseInStream(), CloseOutStream();
- /* Forward */ DotoFilePtr LoadCheatingFromCompiler();
- /* Forward */ Boolean EnsurePresenceOfRequiredTypes();
- /* Forward */ void CodeLoadCallBack();
-
-
- /**************************************************************************/
- /* FindEntryPointForOp */
- /**************************************************************************/
-
- CodeAddr FindEntryPointForOp(fCodePtr, fOpOID)
- CodePtr fCodePtr;
- OID fOpOID;
- {
- register OpVectorPtr ctOpVecPtr;
- register OpVectorEntryPtr entry;
- register int opCount, i;
- /* Implementation note: binary search should be used */
- ctOpVecPtr =
- (OpVectorPtr) addOffset(fCodePtr, fCodePtr->opVecOffset);
- opCount = ctOpVecPtr->numEntries;
- entry = &(ctOpVecPtr->entry[0]);
- for (i = 0 ; i < opCount; entry++, i++)
- if (entry->operationNameOID == fOpOID) {
- KMDTrace("Invoke", 4, "OpOID 0x%08.8x -> (0x%05x) #%d in %s\n",
- fOpOID, addOffset(fCodePtr, entry->offset), i,
- PPCodePtr(fCodePtr));
- return (SSAddr) addOffset(fCodePtr, entry->offset);
- }
- /* Message not understood ???? */
- ErrMsg("OpOID 0x%08.8x not found in %s\n", fOpOID, PPCodePtr(fCodePtr));
- assert (FALSE);
- abort();
- return (SSAddr) EMNIL;
- }
-
- /**************************************************************************/
- /* FindReturnByMoveMask */
- /**************************************************************************/
-
- MoveMask FindReturnByMoveMask(fCodePtr, fEntryPoint)
- CodePtr fCodePtr;
- CodeAddr fEntryPoint;
- {
- register TemplateEntryPtr t;
- register integer i, j;
- register MoveMask theMask;
- TemplatePtr theTemplate;
- Offset entryPointOffset, tOffset;
- IPMapPtr map;
- integer moveIt;
-
- entryPointOffset = (Offset) byteOffset(fCodePtr, fEntryPoint);
- map = (IPMapPtr) addOffset(fCodePtr, fCodePtr->templateMapOffset);
- tOffset = IPMapLookup(map, entryPointOffset);
- assert( 0 != tOffset );
- theTemplate = (TemplatePtr) addOffset(fCodePtr, tOffset);
-
- /* Finally, we have digged out the template */
- t = &theTemplate->entry[0];
- theMask = 0;
- for (i = theTemplate->B.numEntries; i > 0; i--) {
- switch (t->TE.SS.Format) {
- case ShortStaticF: {
- KMDTrace("Invoke", 5,
- "\tShortStaticF\t(%s) %s\tcount =%4d\n",
- PPBrand(t->TE.SS.theBrand),
- PPParamInfo(t->TE.SS.paramInfo),
- t->TE.SS.count);
-
- if (
- (t->TE.SS.paramInfo == IsNotParam) ||
- (t->TE.SS.paramInfo == IsArgument)
- ) {
- i = 0; /* to stop loop (hack, but better than goto) */
- break;
- }
-
- /* moveIt is true iff the param is Move By Result */
- moveIt = (t->TE.SS.paramInfo == IsMoveResult);
- for (j = t->TE.SS.count; --j >= 0;) {
- theMask = (theMask << 1) | moveIt;
- }
- t = (TemplateEntryPtr) addOffset(t, sizeof(ShortStatic));
- break;
- }
- case RegisterF: {
- t = (TemplateEntryPtr) addOffset(t, sizeof(t->TE.R));
- break;
- } /* case RegisterF */
-
- default: {
- i = 0; /* to stop loop, hack, but better than goto */
- break;
- } /* default action */
-
- } /* switch on t->TE.SS.Format */
- } /* for (i = ...) */
- KMDTrace("Invoke", 4, "MoveByResult Mask 0x%08x\n", theMask);
-
- return theMask;
- }
-
- /************************************************************************/
- AbConPtr MakeAbCon(fATODP, fCTODP)
- ATODP fATODP;
- CodeODP fCTODP;
- {
- int opCTCount, opATCount, i, j;
- register AbConPtr newAbConPtr;
- OpVectorPtr ctOpVecPtr, atOpVecPtr;
- CodePtr theCTCode, theATCode;
-
- /* At this point, we have a real AB and a real CON with dataPtr != NULL */
- /* (Note, they might actually be ABAB or CONCON, but we have their code)*/
-
- theCTCode = fCTODP->dataPtr;
- if (theCTCode->opVecOffset == 0) {
- opCTCount = 0;
- } else {
- ctOpVecPtr =
- (OpVectorPtr) addOffset(theCTCode, theCTCode->opVecOffset);
- opCTCount = ctOpVecPtr->numEntries;
- }
-
- theATCode = fATODP->dataPtr;
- if (theATCode->opVecOffset == 0) {
- opATCount = 0;
- } else {
- atOpVecPtr =
- (OpVectorPtr) addOffset(theATCode, theATCode->opVecOffset);
- opATCount = atOpVecPtr->numEntries;
- }
- newAbConPtr = NEWAbCon(opATCount);
- KMDTrace("AbCon", 3, "Make real AbCon(%s, %s) @ 0x%06x\n",
- PPCOID(fATODP->ownOID), PPCOID(fCTODP->ownOID), newAbConPtr);
- KMDTrace("AbCon", 4, "opctCount %d, opatCount %d\n", opCTCount,
- opATCount);
- newAbConPtr->tag = stdAbConTag;
- newAbConPtr->numEntries = opATCount;
- newAbConPtr->tag.hasNoPointer = theCTCode->tag.hasNoPointer;
- newAbConPtr->tag.allInstancesAreLocal = theCTCode->tag.allInstancesAreLocal;
- newAbConPtr->tag.frozen = ~theCTCode->tag.allInstancesAreLocal;
- KMDTrace("AbCon", 5,
- " frozen: %d allInstancesAreLocal %d hasNoPointer %d\n",
- newAbConPtr->tag.frozen, newAbConPtr->tag.allInstancesAreLocal,
- newAbConPtr->tag.hasNoPointer);
- newAbConPtr->ATOID = fATODP->ownOID;
- newAbConPtr->aPtr = theATCode;
- newAbConPtr->CodeOID = fCTODP->ownOID;
- newAbConPtr->cPtr = theCTCode;
- for (i=0, j=0; (i<opATCount) && (j<opCTCount); j++) {
- if (ctOpVecPtr->entry[j].operationNameOID !=
- atOpVecPtr->entry[i].operationNameOID) {
- KMDTrace("AbCon", 5, "CT op #%d [0x%08x] skipped\n", j,
- ctOpVecPtr->entry[j].operationNameOID);
- continue;
- }
- newAbConPtr->opVector[i].opAddress =
- (CodeAddr) addOffset(theCTCode, ctOpVecPtr->entry[j].offset);
- newAbConPtr->opVector[i].argumentCount =
- ctOpVecPtr->entry[j].argumentCount;
- newAbConPtr->opVector[i].resultCount =
- ctOpVecPtr->entry[j].resultCount;
- newAbConPtr->opVector[i].operationNameOID =
- ctOpVecPtr->entry[j].operationNameOID;
- KMDTrace("AbCon", 5, "Op #%d [0x%08x] %d arg%s %d result%s\n",
- i, newAbConPtr->opVector[i].operationNameOID,
- newAbConPtr->opVector[i].argumentCount,
- mPLURAL(newAbConPtr->opVector[i].argumentCount),
- newAbConPtr->opVector[i].resultCount,
- mPLURAL(newAbConPtr->opVector[i].resultCount));
- i++;
- };
- if (i < opATCount) {
- KMDTrace("AbCon", 1, " view mismatch -- contact norm@arizona.edu\n");
- ErrMsg(
- "View mismatch, CT does not conform to AT, see norm@arizona.edu\n");
- ErrMsg("AT 0x%08x CT 0x%08x\n", newAbConPtr->ATOID,
- newAbConPtr->CodeOID);
- assert (FALSE);
- }
- return newAbConPtr;
- }
-
- /**********************************************************************/
- /* MakeAbAb */
- /**********************************************************************/
-
- AbConPtr MakeAbAb(fATODP, fCTODP)
- ATODP fATODP;
- CodeODP fCTODP;
- /* Build an AbCon using the AT only */
- {
- int opATCount, i;
- register AbConPtr newAbConPtr;
- OpVectorPtr atOpVecPtr;
- CodePtr theATCode;
-
- theATCode = fATODP->dataPtr;
- if (theATCode->opVecOffset == 0) {
- opATCount = 0;
- } else {
- atOpVecPtr =
- (OpVectorPtr) addOffset(theATCode, theATCode->opVecOffset);
- opATCount = atOpVecPtr->numEntries;
- }
- newAbConPtr = NEWAbCon(opATCount);
- KMDTrace("AbCon", 3, "MakeAbAb(%s, %s) @ 0x%06x\n",
- PPCOID(fATODP->ownOID), PPCOID(fCTODP->ownOID), newAbConPtr);
- KMDTrace("AbCon", 4, "Operation count %d\n", opATCount);
- newAbConPtr->tag = stdAbConTag;
- newAbConPtr->numEntries = opATCount;
- newAbConPtr->tag.hasNoPointer = theATCode->tag.hasNoPointer;
- newAbConPtr->tag.allInstancesAreLocal =
- theATCode->tag.allInstancesAreLocal;
- newAbConPtr->tag.frozen = ~theATCode->tag.allInstancesAreLocal;
- KMDTrace("AbCon", 5,
- " frozen: %d allInstancesAreLocal %d hasNoPointer %d\n",
- newAbConPtr->tag.frozen, newAbConPtr->tag.allInstancesAreLocal,
- newAbConPtr->tag.hasNoPointer);
- newAbConPtr->ATOID = fATODP->ownOID;
- newAbConPtr->aPtr = theATCode;
- newAbConPtr->CodeOID = fCTODP->ownOID;
- newAbConPtr->cPtr = (CodePtr) NULL;
-
- for (i=0; i<opATCount; i++) {
- newAbConPtr->opVector[i].opAddress = (CodeAddr) NULL;
- newAbConPtr->opVector[i].argumentCount =
- atOpVecPtr->entry[i].argumentCount;
- newAbConPtr->opVector[i].resultCount =
- atOpVecPtr->entry[i].resultCount;
- newAbConPtr->opVector[i].operationNameOID =
- atOpVecPtr->entry[i].operationNameOID;
- KMDTrace("AbCon", 5, "Op #%d [0x%08x] %d arg%s %d result%s\n",
- i, newAbConPtr->opVector[i].operationNameOID,
- newAbConPtr->opVector[i].argumentCount,
- mPLURAL(newAbConPtr->opVector[i].argumentCount),
- newAbConPtr->opVector[i].resultCount,
- mPLURAL(newAbConPtr->opVector[i].resultCount));
- };
- return newAbConPtr;
- }
-
- /**********************************************************************/
- /* MakeConCon */
- /**********************************************************************/
-
- AbConPtr MakeConCon(fATODP, fCTODP)
- ATODP fATODP;
- CodeODP fCTODP;
- {
- int opCTCount, i;
- register AbConPtr newAbConPtr;
- OpVectorPtr ctOpVecPtr;
- CodePtr theCTCode;
-
- theCTCode = fCTODP->dataPtr;
- if (theCTCode->opVecOffset == 0) {
- opCTCount = 0;
- } else {
- ctOpVecPtr =
- (OpVectorPtr) addOffset(theCTCode, theCTCode->opVecOffset);
- opCTCount = ctOpVecPtr->numEntries;
- }
-
- KMDTrace("AbCon", 3, "MakeConCon(0x%05x, 0x%05x)\n", fATODP->ownOID,
- fCTODP->ownOID);
- KMDTrace("AbCon", 4, "ConCon %d operation%s\n", opCTCount,
- mPLURAL(opCTCount));
- newAbConPtr = NEWAbCon(opCTCount);
- newAbConPtr->tag = stdAbConTag;
- newAbConPtr->numEntries = opCTCount;
- newAbConPtr->tag.hasNoPointer = theCTCode->tag.hasNoPointer;
- newAbConPtr->tag.allInstancesAreLocal =
- theCTCode->tag.allInstancesAreLocal;
- newAbConPtr->tag.frozen = ~theCTCode->tag.allInstancesAreLocal;
- KMDTrace("AbCon", 5,
- " frozen: %d allInstancesAreLocal %d hasNoPointer %d\n",
- newAbConPtr->tag.frozen, newAbConPtr->tag.allInstancesAreLocal,
- newAbConPtr->tag.hasNoPointer);
- newAbConPtr->ATOID = fATODP->ownOID;
- newAbConPtr->aPtr = (CodePtr) NULL;
- newAbConPtr->CodeOID = fCTODP->ownOID;
- newAbConPtr->cPtr = theCTCode;
-
- for (i=0; i<opCTCount; i++) {
- newAbConPtr->opVector[i].opAddress =
- (CodeAddr) addOffset(theCTCode, ctOpVecPtr->entry[i].offset);
- newAbConPtr->opVector[i].argumentCount =
- ctOpVecPtr->entry[i].argumentCount;
- newAbConPtr->opVector[i].resultCount =
- ctOpVecPtr->entry[i].resultCount;
- newAbConPtr->opVector[i].operationNameOID =
- ctOpVecPtr->entry[i].operationNameOID;
- KMDTrace("AbCon", 5, "Op #%d [0x%08x] %d arg%s %d result%s\n",
- i, newAbConPtr->opVector[i].operationNameOID,
- newAbConPtr->opVector[i].argumentCount,
- mPLURAL(newAbConPtr->opVector[i].argumentCount),
- newAbConPtr->opVector[i].resultCount,
- mPLURAL(newAbConPtr->opVector[i].resultCount));
- };
- return newAbConPtr;
- }
-
- /**********************************************************************/
- /* MakeFakeAbCon */
- /**********************************************************************/
-
- AbConPtr MakeFakeAbCon(fATODP, fCTODP)
- ATODP fATODP;
- CodeODP fCTODP;
- {
- register AbConPtr newAbConPtr;
-
- newAbConPtr = NEWAbCon(100);
- newAbConPtr->tag = stdAbConTag;
- newAbConPtr->numEntries = 0;
- newAbConPtr->ATOID = fATODP->ownOID;
- newAbConPtr->CodeOID = fCTODP->ownOID;
- newAbConPtr->aPtr = (ATPtr) NULL;
- newAbConPtr->cPtr = (CodePtr) NULL;
- newAbConPtr->tag.hasNoPointer = TRUE;
- newAbConPtr->tag.allInstancesAreLocal = TRUE;
- newAbConPtr->tag.frozen = FALSE;
-
- KMDTrace("AbCon", 3, "AbCon(0x%05x, 0x%05x) had to be faked\n",
- fATODP->ownOID, fCTODP->ownOID);
- return (newAbConPtr);
- }
-
- /**********************************************************************/
- /* ReDoAbCon */
- /**********************************************************************/
- void ReDoAbCon(fAbConPtr)
- AbConPtr fAbConPtr;
- {
- CodeODP theCodeODP;
- ATODP theATODP;
- CodePtr theCodePtr, theATCodePtr;
- OpVectorPtr ctOpVecPtr, atOpVecPtr;
- int opCTCount, opATCount, i, j;
-
- KMDTrace("AbCon", 3, "ReDoAbCon (%s, %s, %s)\n", PPCOID(fAbConPtr->ATOID),
- PPCOID(fAbConPtr->restrictOID), PPCOID(fAbConPtr->CodeOID));
-
- theCodeODP = (CodeODP) OTLookup(fAbConPtr->CodeOID);
- if (NonNULL(theCodeODP) && NonNULL(theCodeODP->dataPtr)) {
- theCodePtr = theCodeODP->dataPtr;
-
- fAbConPtr->cPtr = theCodePtr;
-
- ctOpVecPtr =
- (OpVectorPtr) addOffset(theCodePtr, theCodePtr->opVecOffset);
- opCTCount = ctOpVecPtr->numEntries;
- }
-
- theATODP = (ATODP) OTLookup(fAbConPtr->ATOID);
- if (NonNULL(theATODP) && NonNULL(theATODP->dataPtr)) {
- theATCodePtr = theATODP->dataPtr;
- fAbConPtr->aPtr = theATCodePtr;
- }
-
- /* Now check to see, if we actually are able to redo the abcon */
- if (IsNULL(fAbConPtr->aPtr) || IsNULL(fAbConPtr->cPtr)) {
- KMDTrace("AbCon", 3, "Still have a piece missing, no final fixup\n");
- return;
- }
-
- theATODP->tag.frozen =
- theATODP->tag.setUpDone =
- theATODP->tag.isResident = TRUE;
-
- if (IsNULL(theATCodePtr->opVecOffset)) {
- KMDTrace("AbCon", 3, "Redoing AT with no op vector -- done\n");
- return;
- }
-
- atOpVecPtr =
- (OpVectorPtr) addOffset(theATCodePtr, theATCodePtr->opVecOffset);
- opATCount = atOpVecPtr->numEntries;
-
- KMDTrace("AbCon", 4, "Op count: AT has %d ops; CT has %d ops\n",
- opATCount, opCTCount);
-
- for (i=0, j=0; (i<opATCount) && (j<opCTCount); j++) {
- if (ctOpVecPtr->entry[j].operationNameOID !=
- atOpVecPtr->entry[i].operationNameOID) {
- KMDTrace("AbCon", 5, "CT op #%d [0x%08x] skipped\n", j,
- ctOpVecPtr->entry[j].operationNameOID);
- continue;
- }
- fAbConPtr->opVector[i].opAddress =
- (CodeAddr) addOffset(theCodePtr, ctOpVecPtr->entry[j].offset);
- fAbConPtr->opVector[i].argumentCount =
- ctOpVecPtr->entry[j].argumentCount;
- fAbConPtr->opVector[i].resultCount =
- ctOpVecPtr->entry[j].resultCount;
- fAbConPtr->opVector[i].operationNameOID =
- ctOpVecPtr->entry[j].operationNameOID;
- KMDTrace("AbCon", 5, "Op #%d [0x%08x] %d arg%s %d result%s\n",
- i, fAbConPtr->opVector[i].operationNameOID,
- fAbConPtr->opVector[i].argumentCount,
- mPLURAL(fAbConPtr->opVector[i].argumentCount),
- fAbConPtr->opVector[i].resultCount,
- mPLURAL(fAbConPtr->opVector[i].resultCount));
- i++;
- };
- if (i < opATCount) {
- KMDTrace("AbCon", 1, " view mismatch -- contact norm@arizona\n");
- ErrMsg("View mismatch, CT does not conform to AT -- contact norm\n");
- ErrMsg("AT %s CT %s\n", PPCOID(fAbConPtr->ATOID),
- PPCOID(fAbConPtr->CodeOID));
- (void) fflush(stdout);
- (void) fflush(stderr);
- assert (FALSE);
- abort();
- }
- }
-
- /**********************************************************************/
- /* InsertUnknownATAbConMap */
- /**********************************************************************/
- void InsertUnknownATAbConMap(fAbConPtr)
- register AbConPtr fAbConPtr;
- {
- Set theSet;
-
- KMDTrace("AbCon", 3, "Inserting (AT %s, CT %s) into UnknownATAbConMap\n",
- PPCOID(fAbConPtr->ATOID), PPCOID(fAbConPtr->CodeOID));
- theSet = (Set) Map_Lookup(UnknownATAbConMap, (int) (fAbConPtr->ATOID));
- if (IsNIL(theSet)) {
- KMDTrace("AbCon", 5, "First abcon, creating set.\n");
- theSet = Set_Create();
- Map_Insert(UnknownATAbConMap, (int) fAbConPtr->ATOID, (int) theSet);
- }
- Set_Insert(theSet, (int) fAbConPtr);
- }
- /**********************************************************************/
- /* OIDOIDOIDToAbCon */
- /**********************************************************************/
-
- AbConPtr OIDOIDOIDToAbCon(fATOID, fROID, fCTOID)
- OID fATOID, fROID, fCTOID;
- /* Construct an AbCon vector given an Abstract OID and a code OID */
- {
- register AbConPtr newAbConPtr;
- CodeODP theCodeODP;
- ATODP theATODP;
-
- newAbConPtr = (AbConPtr)
- Map96_Lookup(AbConMap96, (int) fATOID, (int) fROID, (int) fCTOID);
-
- if (NonNIL(newAbConPtr)) {
- KMDTrace("AbCon", 5, "AbCon(0x%05x, 0x%05x, 0x%05x) @ 0x%05x\n",
- fATOID, fROID, fCTOID, newAbConPtr);
- KMDTrace("AbCon", 5, "Returning known abcon (0x%06x)\n", newAbConPtr);
- return newAbConPtr;
- }
-
- /*
- * This abcon unknown, so construct it.
- * An optimization would be to construct it from an earlier one.
- */
-
- theCodeODP = (CodeODP) OTLookup(fCTOID);
- if (IsNULL(theCodeODP)) {
- /* Then create one */
- theCodeODP = CreateCodeODEntry(fCTOID, (EmLocation) NULL);
- }
- theATODP = (CodeODP) OTLookup(fATOID);
- if (IsNULL(theATODP)) {
- /* Then create one */
- theATODP = CreateCodeODEntry(fATOID, (EmLocation) NULL);
- }
-
- if (IsNULL(theCodeODP->dataPtr)) {
- /* The code is unknown */
- if (IsNULL(theATODP->dataPtr)) {
- /* Unknown Code, unknown Ab */
- newAbConPtr = MakeFakeAbCon(theATODP, theCodeODP);
- } else {
- /* Unknown Code, know ab */
- newAbConPtr = MakeAbAb(theATODP, theCodeODP);
- }
- } else {
- /* The code is known */
- if (IsNULL(theATODP->dataPtr)) {
- /* Known Code, unknown Ab */
- newAbConPtr = MakeConCon(theATODP, theCodeODP);
- } else {
- /* Known Code, known ab */
- newAbConPtr = MakeAbCon(theATODP, theCodeODP);
- }
- }
-
- newAbConPtr->restrictOID = fROID;
-
- Map96_Insert(AbConMap96, (int) fATOID, (int) fROID, (int) fCTOID,
- (int) newAbConPtr);
-
- KMDTrace("AbCon", 5, "New AbCon(0x%05x, 0x%05x, 0x%05x) @ 0x%05x\n",
- fATOID, fROID, fCTOID, newAbConPtr);
-
- /* Put reference to abcon into the concrete OD */
- Set_Insert((Set)(theCodeODP->AbConSetPtr), (int) newAbConPtr);
-
- /* If the AT is unknown put the abcon into the redo list */
- if (IsNULL(newAbConPtr->aPtr)) {
- /* Put the new abcon into the UnknownATAbConMap */
- InsertUnknownATAbConMap(newAbConPtr);
- }
- return(newAbConPtr);
- }
-
- /**********************************************************************/
- /* GetAbCon */
- /**********************************************************************/
-
- AbConPtr GetAbCon(fATOID, fROID, fCTOID, fTag)
- OID fATOID, fROID, fCTOID;
- ODTag fTag;
- /* Construct an AbCon vector given an Abstract OID, a code OID, and a tag */
- {
- register AbConPtr newAbConPtr;
- CodeODP theCodeODP;
-
- newAbConPtr = OIDOIDOIDToAbCon(fATOID, fROID, fCTOID);
- KMDTrace("AbCon", 3, "GetAbCon(0x%05x, 0x%05x 0x%05x) @ 0x%05x\n", fATOID,
- fROID, fCTOID, newAbConPtr);
- theCodeODP = (CodeODP) OTLookup(fCTOID);
- if (IsNULL(theCodeODP) || IsNULL(theCodeODP->dataPtr)){
- /* Use the given tag */
- newAbConPtr->tag = fTag;
- } else {
- assert (theCodeODP->dataPtr->tag.hasNoPointer == fTag.hasNoPointer);
- assert(theCodeODP->dataPtr->tag.allInstancesAreLocal == fTag.allInstancesAreLocal);
- }
- return(newAbConPtr);
- }
-
- /**********************************************************************/
- /* ChangeViewPtr */
- /**********************************************************************/
-
- /* Kernel entry */
- void ChangeViewPtr(fOldAbConPtr, fNewATPtr)
- register AbConPtr fOldAbConPtr;
- register ATPtr fNewATPtr;
- /* Return an abcon vector for the new view */
- /* Guarenteed to work */
- {
- KMDTrace("View", 3, "Changing view from (%s, %s) to (%s, %s)\n",
- PPCOID(fOldAbConPtr->ATOID), PPCOID(fOldAbConPtr->CodeOID),
- PPCOID(fNewATPtr->ownOID), PPCOID(fOldAbConPtr->CodeOID));
- currentSSP->resultBrand = ODPBrand;
- currentSSP->regs.arg1 =
- (int) OIDOIDOIDToAbCon(fNewATPtr->ownOID, fOldAbConPtr->restrictOID,
- fOldAbConPtr->CodeOID);
- }
-
- /**********************************************************************/
- /**********************************************************************/
- /* Code dependencies */
- /**********************************************************************/
-
- /**********************************************************************/
- /* Often a piece of code has dependencies on another piece of code */
- /* in the form of jump instructions. When the destination code is */
- /* non-resident, the jump instruction is made to jump to a kernel */
- /* error routine. */
- /* During translation of the jump instruction, a code dependency is */
- /* generated so that should the code ever become resident then the */
- /* jump instruction can be fixed-up with the correct address. */
- /**********************************************************************/
-
- /**********************************************************************/
- /* CodeDependency */
- /**********************************************************************/
-
- void CodeDependency(fDependentOID, fNonResidentOID)
- OID fDependentOID; /* OID for dependent */
- OID fNonResidentOID; /* OID for the non-resident code*/
- /* Generate fDependentOID dependes on fNonResidentOID */
- {
- CodeODP theCodeODP;
-
- theCodeODP = CreateCodeODEntry(fNonResidentOID, (EmLocation) NULL);
- if (IsNULL(theCodeODP->depCode))
- theCodeODP->depCode = (GenericPtr) Set_Create();
- /* Using Set instead of Bag (since Bag is yet to be defined) */
- Set_Insert((Set) theCodeODP->depCode, (int) fDependentOID);
- KMDTrace("Code", 3, "(%s) depends on (%s)\n", PPCOID(fDependentOID),
- PPCOID(fNonResidentOID));
- }
-
- /**********************************************************************/
- /* CodeArrived */
- /**********************************************************************/
-
- void CodeArrived(fCodeODP)
- CodeODP fCodeODP;
- {
- OID depCodeOID;
- CodeODP depCodeODP;
- OID loadOID;
- CodeLoadReqPtr req;
- AbConPtr theAbConPtr;
- Set theSet;
-
- loadOID = fCodeODP->ownOID;
- fCodeODP->tag.isResident = TRUE;
-
- KMDTrace("Code", 3, "%s arrived; checking dependencies\n",
- PPCodePtr(fCodeODP->dataPtr));
-
- /* Check for code dependencies */
- if (NonNULL(fCodeODP->depCode)) {
- KMDTrace("Code", 3, "%d dependencies\n",
- Set_Count((Set) fCodeODP->depCode));
- Set_For(((Set) fCodeODP->depCode), depCodeOID)
- depCodeODP = (CodeODP) OTLookup(depCodeOID);
- if (IsNULL(depCodeODP)) continue;
- retranslate(depCodeODP);
- Set_Next
- Set_Destroy((Set) fCodeODP->depCode);
- fCodeODP->depCode = (GenericPtr) NULL;
- }
-
- /* Check for AbCons to fix */
- theSet = (Set) (fCodeODP->AbConSetPtr);
- if (NonNULL(theSet) && (Set_Count(theSet) > 0)) {
- KMDTrace("Code", 3, "Checking %d AbCons on arrival of CT %s\n",
- Set_Count(theSet), PPCodePtr(fCodeODP->dataPtr));
- Set_For(theSet, theAbConPtr)
- KMDTrace("Code", 3, "Redoing AbCon 0x%04x\n", theAbConPtr);
- ReDoAbCon(theAbConPtr);
- Set_Next
- }
-
- /* Check to see if this is a previously unknown AT that has
- AbCons */
- theSet = (Set) Map_Lookup(UnknownATAbConMap, (int) loadOID);
- if (NonNIL(theSet)) {
- KMDTrace("AbCon", 5, "Redoing %d AbCons for newly resident AT %s\n",
- Set_Count(theSet), PPCOID(loadOID));
-
- Set_For(theSet, theAbConPtr)
- KMDTrace("AbCon", 5, "Redoing for CT %s\n",
- PPCOID(theAbConPtr->CodeOID));
- ReDoAbCon(theAbConPtr);
- Set_Next;
-
- /* Now that the AbCons have been redone, delete from unknown map */
- Map_Delete(UnknownATAbConMap, (int) loadOID);
- Set_Destroy(theSet);
- }
-
- /* Check for outstanding remote code load requests */
- req = (CodeLoadReqPtr) Map_Lookup(RemoteLoadMap, (int) loadOID);
- if (NonNIL(req)) {
- KMDTrace("Code", 3,
- "Code arrival causes unblocking of load request\n");
- Map_Delete(RemoteLoadMap, (int) loadOID);
- CodeLoadCallBack(req, loadOID);
- }
- }
-
- /**********************************************************************/
- /**********************************************************************/
-
- /**********************************************************************/
- /* KernelCheatingCreate */
- /**********************************************************************/
-
- ODP KernelCheatingCreate(fOID, fCodeOID, fParamCount, fParamArray)
- OID fOID, fCodeOID;
- int fParamCount;
- AVariable fParamArray[];
- /* Let the kernel create an object with the given OID and run its initially
- with the given parameters */
- {
- SSPtr p;
- CodeODP theCodeODP;
- CodePtr theCode;
- ODP theObj;
- int i;
-
- KMDTrace("Create", 2, "Cranking up object %s; one of %s\n",
- PPGOID(fOID), PPCOID(fCodeOID));
- theCodeODP = (CodeODP) OTLookup(fCodeOID);
- assert(NonNULL(theCodeODP));
- theCode = theCodeODP->dataPtr;
- theObj = (ODP) AllocateWithOID(theCode, fOID, theCode->instanceSize);
- if (theCode->initially.offset) {
- /* Has an initially (InitiallyDone does the process) */
- KMDTrace("Create", 3,
- "Starting initially for one of %s, %d argument%s\n",
- PPCOID(fCodeOID), fParamCount, mPLURAL(fParamCount));
- p = NewProcess();
- for (i=0; i < fParamCount; i++) {
- PUSHIT(p->regs.sp, fParamArray[i].myAbConPtr);
- PUSHIT(p->regs.sp, fParamArray[i].myAddr);
- }
- StartProcessAtAddr(p, (GODP) theObj,
- (theObj->G.tag.global ? theObj->G.dataPtr : (GODataPtr) theObj),
- (CodeAddr) addOffset(theCode, theCode->initially.offset));
- } else {
- if (theObj->G.tag.global) {
- theObj->G.tag.setUpDone = TRUE;
- theObj->G.tag.frozen = FALSE;
- UnblockInitially((GODP)theObj);
- }
- if (theCode->process.offset) {
- /* No initially, but a process -- fire it up */
- KMDTrace("Code", 3, "Starting its process\n");
- p = NewProcess();
- StartProcessAtAddr(p, (GODP) theObj, (GODataPtr) theObj,
- (CodeAddr) addOffset(theCode, theCode->process.offset));
- }
- }
- return theObj;
- }
- /**********************************************************************/
- void CheatingCreateCodeLoadDone(fReq, fCodeOID)
- CheatingLoadReqPtr fReq;
- OID fCodeOID;
- {
- ODP newObj;
- register CheatingLoadReqPtr req = fReq;
-
- KMDTrace("Create", 3, "Creating %s; one of %s\n", PPGOID(req->theObjOID),
- PPCOID(req->theCodeOID));
- assert(req->theCodeOID == fCodeOID);
- newObj = KernelCheatingCreate(req->theObjOID, req->theCodeOID, 0, NULL);
- OTInsert(newObj);
- newObj->G.ownLoc = thisNodeLocation;
- newObj->G.tag.isResident = TRUE;
- newObj->G.tag.frozen = !newObj->G.tag.setUpDone;
- KMDTrace("FixMe", 3, "Should set the frozen bit right\n");
- Map_Delete(CheatingLoadMap, (int) req->theObjOID);
- DoCallBack((GenericReqPtr) req, req->theObjOID);
- /* Check to see if there are location requests for this one */
- FreeRequest((GenericReqPtr) req);
- }
-
- /**********************************************************************/
- /* CheatingCrankupHandler */
- /**********************************************************************/
-
- void CheatingCrankupHandler(fOID)
- OID fOID;
- {
- register GODP theODP;
- DotoFilePtr doto;
- OID theCodeOID;
- CodePtr theCode;
- CheatingLoadReqPtr req;
-
- KMDTrace("Create", 3, "Performing Cheating Create for %s\n",
- PPGOID(fOID));
- theODP = (GODP) OTLookup(fOID);
- if (IsNULL(theODP)) {
- KMDTrace("Create", 2, "Object unknown in Cheating Crankup\n");
- return;
- }
- if (theODP->tag.setUpDone) {
- KMDTrace("Create", 3, "Already done\n");
- return;
- }
-
- /* Load the code and find its OID */
- doto = LoadCheatingFromCompiler(fOID);
- if (IsNULL(doto)) {
- KMDTrace("Create", 2, "Did not find %s on disk ?\n", PPGOID(fOID));
- return;
- }
- theCode = dotoCodePtr(doto);
- theCodeOID = theCode->ownOID;
- req = mNewRequest(CheatingLoad);
- req->status = FoundSomewhere;
- req->hdr.callBack = (GenericHandlerPtr) CheatingCreateCodeLoadDone;
- req->theObjOID = fOID;
- req->theCodeOID = theCodeOID;
-
- KMDTrace("Code", 4, "Start translation of %s\n", PPCOID(theCodeOID));
- Map_Insert(CheatingLoadMap, (int) fOID, (int) req);
- if (LoadRequest(theCodeOID, (GenericReqPtr) req)) {
- req->status = Translated;
- KMDTrace("Code", 4, "Code loaded, now crank up\n");
- CheatingCreateCodeLoadDone(req, req->theCodeOID);
- }
- }
-
- /**********************************************************************/
- /* StartCheatingCrankup */
- /**********************************************************************/
-
- void StartCheatingCrankup(fOID, fReq)
- OID fOID;
- GenericReqPtr fReq;
- /* Do a cheating creation of an object whose code is on our own disk */
- {
- register GODP theODP;
- DotoFilePtr doto;
- OID theCodeOID;
- CodePtr theCode;
- CheatingLoadReqPtr req;
-
- KMDTrace("Create", 3, "Cheating Create for %s from own disk.\n",
- PPGOID(fOID));
- theODP = (GODP) OTLookup(fOID);
- if (IsNULL(theODP)) {
- KMDTrace("Create", 2, "Object unknown in Cheating Crankup\n");
- return;
- }
- if (theODP->tag.setUpDone) {
- KMDTrace("Create", 3, "Already done\n");
- return;
- }
-
- /* Load the code and find its OID */
- doto = LoadCheatingFromCompiler(fOID);
- if (IsNULL(doto)) {
- KMDTrace("Create", 2, "Did not find %s on disk ?\n", PPGOID(fOID));
- return;
- }
- theCode = dotoCodePtr(doto);
- theCodeOID = theCode->ownOID;
- req = mNewRequest(CheatingLoad);
- req->status = FoundSomewhere;
- req->hdr.callBack = (GenericHandlerPtr) CheatingCreateCodeLoadDone;
- req->theObjOID = fOID;
- req->theCodeOID = theCodeOID;
-
- KMDTrace("Code", 4, "Start translation of %s\n", PPCOID(theCodeOID));
- Map_Insert(CheatingLoadMap, (int) fOID, (int) req);
- Map_Insert(fReq->hdr.wantList, (int) req, 0);
- Map_Insert(req->hdr.reqBy, (int) fReq, 0);
- if (LoadRequest(theCodeOID, (GenericReqPtr) req)) {
- req->status = Translated;
- KMDTrace("Code", 4, "Code loaded, now crank up\n");
- CheatingCreateCodeLoadDone(req, req->theCodeOID);
- }
- }
-
- /**********************************************************************/
- /* Translation routines */
- /**********************************************************************/
-
- RODataPtr OIDToODAP(fOID, fCodeOID)
- OID fOID, fCodeOID;
- /* Translate OID to RODataPtr; if necessary, crank up the object */
- {
- RODataPtr dataPtr;
-
- dataPtr = (RODataPtr) OTLookup(fOID);
- if (IsNULL(dataPtr)) {
- dataPtr = (RODataPtr) KernelCheatingCreate(fOID, fCodeOID, 0, 0);
- assert(NonNULL(dataPtr));
- }
- return dataPtr;
- }
-
- unsigned int OpNumberToAddress(fOID, fOpNumber)
- OID fOID;
- int fOpNumber;
- {
- register ODP p;
- register CodePtr theCode;
- register OpVectorPtr theOpVec;
- register CodeOffset theOffset;
-
- p = (ODP) OTLookup(fOID);
- if (IsNULL(p) || (p->C.tag.tag != CodeODTag) || IsNULL(p->C.dataPtr)) {
- KMDTrace("Translate", 3, "Did not have code %s present\n",
- PPCOID(fOID));
- /* return 0 to indicate that code is not here */
- return((unsigned int) 0);
- }
- if (p->C.dataPtr->opVecOffset == 0) {
- KMDPrint("OpNumberToAddress: Code OID 0x%08x has no OpVector\n",
- fOID);
- _longjmp(errorExitPoint, 4);
- }
- theCode = p->C.dataPtr;
- theOpVec = (OpVectorPtr) addOffset(theCode, theCode->opVecOffset);
- if ((theOpVec->numEntries <= fOpNumber) || (fOpNumber < 0)) {
- KMDPrint("OpNumberToAddress: Code OID 0x%08x OpNumber %d invalid\n",
- fOID, fOpNumber);
- _longjmp(errorExitPoint, 5);
- }
- theOffset = theOpVec->entry[fOpNumber].offset;
- if (IsNULL(theOffset)) {
- KMDPrint("OpNumberToAddress: Code OID 0x%08x OpVector[%d] invalid\n",
- fOID, fOpNumber);
- _longjmp(errorExitPoint, 6);
- }
- return((unsigned int) addOffset(theCode, theOffset));
- }
-
-
- /**********************************************************************/
- /* FLLoadFile */
- /**********************************************************************/
-
- void FLLoadFile(fCount, fName)
- int fCount;
- char *fName;
- {
- time_t theTime = time((time_t *) 0);
- DotoFilePtr dotoFilePtr[MAXDOTOFILES];
- CodePtr theCode;
- CodeODP myCodeODP;
- CreateDirectivePtr cdPtr;
- register int i, j;
- char fileName[400];
- int val;
- Map createdObj;
- int createdObjCount, c;
- GODP x;
-
- createdObj = Map_Create();
- createdObjCount = 0;
-
- if (val = _setjmp(errorExitPoint)) {
- /* This means we longjmp to here upon detecting an error */
- KMDPrint("File load error -- request aborted at %d.\n", val);
- /* Clean up (nothing for now) */
- Map_Destroy(createdObj);
- return;
- }
-
- KMDTrace("Code", 2, "Dynamic load request arrived %s\n", ctime(&theTime));
- KMDTrace("Code", 2, "File base name %s, %d files\n",
- fName, fCount);
- KMDPrint("File base name %s, %d files\n", fName, fCount);
-
- if ( fCount >= MAXDOTOFILES) {
- KMDPrint("Too many .o files: %d -- only %d allowed.\n", fCount,
- MAXDOTOFILES);
- Map_Destroy(createdObj);
- return;
- }
-
- if ( fCount < 0) {
- KMDPrint("File count negative.\n");
- KMDPrint(" *** Aborting load request ***\n");
- Map_Destroy(createdObj);
- return;
- }
-
- /* Phase 1: Read in the files */
- for (i=0; i < fCount; i++) {
- sprintf(fileName, "%s.%d.o", fName, i);
- KMDPrint("Loading file #%d %s\n", i, fileName);
- dotoFilePtr[i] = readDotoFile(fileName);
- if (IsNULL(dotoFilePtr[i])) {
- KMDPrint("File %s cannot be read as a valid .o file\n", fileName);
- _longjmp(errorExitPoint, 1);
- };
- theCode = dotoCodePtr(dotoFilePtr[i]);
- KMDTrace("Code", 3, "File %s, Code OID 0x%08x Em version %s\n", fileName,
- theCode->ownOID, ctime(&theCode->emVersion));
- KMDPrint("Code OID 0x%08x\n", theCode->ownOID);
- if (theCode->emVersion != EMVERSION) {
- time_t emVersion = EMVERSION;
- KMDPrint("File %s version mismatch\n", fileName);
- KMDPrint("File Em version: %s", ctime(&theCode->emVersion));
- KMDPrint("Kernel version: %s", ctime(&emVersion));
- _longjmp(errorExitPoint, 8);
- }
- };
-
- /* Phase 2: Create the code objects and the objects according to the
- Create directives. Creation proceeds in the inverse order, so that
- OIDs should still be allocated in ascending order. */
-
- for (i=fCount-1; i>=0; i--) {
- /* First, create a CodeOD for the CodeObject */
- theCode = dotoCodePtr(dotoFilePtr[i]);
- myCodeODP = (CodeODP) emalloc(sizeof(CodeOD));
- myCodeODP->tag = stdCodeODTag;
- myCodeODP->ownOID = theCode->ownOID;
- myCodeODP->dataPtr = theCode;
- myCodeODP->AbConSetPtr = (GenericPtr) Set_Create();
- myCodeODP->depCode = (GenericPtr) NULL;
-
- /* Insert it into the Object Table */
- OTInsert((ODP) myCodeODP);
-
- /* Now do the create directives */
- cdPtr = dotoCreateDirectivePtr(dotoFilePtr[i]);
- if(cdPtr->numEntries > 0) {
- KMDPrint("\nCreate directive for file #%d, make %d object%s:\n",
- i, cdPtr->numEntries, mPLURAL(cdPtr->numEntries));
- for (j = 0; j < cdPtr->numEntries; j++) {
- x = AllocateWithOID(theCode, cdPtr->createOID[j],
- theCode->instanceSize);
- createdObjCount++;
- Map_Insert(createdObj, createdObjCount, (int) x);
- KMDPrint("\t%s\n", IsNULL(cdPtr->createOID[j]) ?
- "ANONYMOUS" : PPGOID(cdPtr->createOID[j]));
- }
- }
- }
-
- /* Phase 3: Translate the OIDs in the file and relocate ref to
- global variables. */
-
- for (i=fCount-1; i>=0; i--) {
- translateDoto(dotoFilePtr[i]);
- };
-
- /* Phase 4: Fire up the necessary processes. */
- c = 0;
- for (i = 0; i < fCount; i++) {
- /* Now do the create directives */
- cdPtr = dotoCreateDirectivePtr(dotoFilePtr[i]);
- for (j = 0; j < cdPtr->numEntries; j++) {
- SSPtr p;
- GODP theObj;
- CodePtr cPtr = dotoCodePtr(dotoFilePtr[i]);
- c++;
- theObj = (GODP) Map_Lookup(createdObj, c);
- if (theObj == (GODP) EMNIL) {
- KMDPrint("Lookup of created object %s failed\n",
- PPGOID(cdPtr->createOID[j]));
- _longjmp(errorExitPoint, 2);
- }
- if(cPtr->initially.offset) {
- /* Has an initially (InitiallyDone does the process) */
- p = NewProcess();
- StartProcessAtAddr(p, theObj, theObj->dataPtr,
- (CodeAddr) addOffset(cPtr, cPtr->initially.offset));
- } else {
- theObj->tag.setUpDone = TRUE;
- theObj->tag.frozen = FALSE;
- if (cPtr->process.offset) {
- /* No initially, but a process -- fire it up */
- p = NewProcess();
- KMDPrint("Firing up process %s in object %s\n",
- PPPOID(p->processOID), IsNULL(theObj->ownOID) ?
- "ANONYMOUS" : PPGOID(theObj->ownOID));
- StartProcessAtAddr(p, theObj, theObj->dataPtr,
- (CodeAddr) addOffset(cPtr, cPtr->process.offset));
- }
- }
- }
- }
- Map_Destroy(createdObj);
- KMDPrint("\nLoad successfully completed\n");
- }
-
- /**************************************************************************/
- void FLCreateOneOfCTOID(fCTOID)
- OID fCTOID;
- {
- CodeODP theCodeODP;
- CodePtr theCode;
- OID newOID;
- GODP theObj;
- SSPtr p;
-
- theCodeODP = (CodeODP) OTLookup(fCTOID);
- if (IsNULL(theCodeODP) || theCodeODP->tag.tag != CodeODTag) {
- KMDPrint("0x%05x is not a valid Code OID\n", fCTOID);
- return;
- }
- newOID = getNextOID();
- theCode = theCodeODP->dataPtr;
- if (theCode->initially.argumentCount >0) {
- KMDPrint("Cannot create: arg count >0 (is %d) for Code %s\n",
- theCode->initially.argumentCount, PPCOID(fCTOID));
- return;
- }
- theObj = MakeObject(theCode, newOID, theCode->instanceSize);
- KMDPrint("Create object OID 0x%05x; one of %s\n", newOID,
- PPCOID(fCTOID));
- if(theCode->initially.offset) {
- /* Has an initially (InitiallyDone does the process) */
- p = NewProcess();
- StartProcessAtAddr(p, theObj, theObj->dataPtr,
- (CodeAddr) addOffset(theCode, theCode->initially.offset));
- } else {
- theObj->tag.setUpDone = TRUE;
- theObj->tag.frozen = FALSE;
- if (theCode->process.offset) {
- /* No initially, but a process -- fire it up */
- p = NewProcess();
- StartProcessAtAddr(p, theObj, theObj->dataPtr,
- (CodeAddr) addOffset(theCode, theCode->process.offset));
- }
- }
-
- }
-
- /**************************************************************************/
- DotoFilePtr FLReadInDoto(fName)
- char *fName;
- {
- time_t theTime = time((time_t *) 0);
- DotoFilePtr dotoFilePtr;
- CodePtr theCode;
- CodeODP myCodeODP;
- CreateDirectivePtr cdPtr;
- register int j;
- char fileName[400];
- int val;
-
- if (val = _setjmp(errorExitPoint)) {
- /* This means we longjmp to here upon detecting an error */
- ErrMsg("File load error -- request aborted at %d.\n", val);
- /* Clean up (nothing for now) */
- return (DotoFilePtr) NULL;
- }
-
- KMDTrace("Code", 5, "Reading %s at %-15.15s\n", fName, 4+ctime(&theTime));
- /* Phase 1: Read in the file */
- sprintf(fileName, "%s", fName);
- dotoFilePtr = readDotoFile(fileName);
- if (IsNULL(dotoFilePtr)) {
- ErrMsg("File %s cannot be read as a valid .o file\n", fileName);
- _longjmp(errorExitPoint, 1);
- };
- theCode = dotoCodePtr(dotoFilePtr);
- KMDTrace("Code", 3, "File %s, Code OID 0x%08x\n", fileName, theCode->ownOID);
- KMDTrace("Code", 5, "Em version %-15.15s\n",4+ctime(&theCode->emVersion));
- if (theCode->emVersion != EMVERSION) {
- time_t emVersion = EMVERSION;
- ErrMsg("File %s version mismatch\n", fileName);
- ErrMsg("File Em version: %s", ctime(&theCode->emVersion));
- ErrMsg("Kernel version: %s", ctime(&emVersion));
- _longjmp(errorExitPoint, 8);
- }
-
- /* Phase 2: Create the code objects and the objects according to the
- Create directives. Creation proceeds in the inverse order, so that
- OIDs should still be allocated in ascending order. */
-
- /* First, create a CodeOD for the CodeObject */
- theCode = dotoCodePtr(dotoFilePtr);
- myCodeODP = (CodeODP) emalloc(sizeof(CodeOD));
- myCodeODP->tag = stdCodeODTag;
- myCodeODP->ownOID = theCode->ownOID;
- myCodeODP->dataPtr = theCode;
- myCodeODP->AbConSetPtr = (GenericPtr) Set_Create();
- myCodeODP->depCode = (GenericPtr) NULL;
-
- /* Insert it into the Object Table */
- OTInsert((ODP) myCodeODP);
-
- /* Now do the create directives */
- cdPtr = dotoCreateDirectivePtr(dotoFilePtr);
- if (cdPtr->numEntries > 0) {
- KMDTrace("Code", 3, "Create directive make %d object%s:\n",
- cdPtr->numEntries, mPLURAL(cdPtr->numEntries));
- for (j = 0; j < cdPtr->numEntries; j++) {
- (void) AllocateWithOID(theCode, cdPtr->createOID[j],
- theCode->instanceSize);
- KMDTrace("Code", 3, "\t%0.8x\n", cdPtr->createOID[j]);
- }
- }
- return dotoFilePtr;
- }
-
- /**************************************************************************/
- void FLTranslateAndActivateDoto(fDotoFilePtr)
- DotoFilePtr fDotoFilePtr;
- {
- DotoFilePtr dotoFilePtr = fDotoFilePtr;
- CodePtr theCode;
- CodeODP theCodeODP;
- CreateDirectivePtr cdPtr;
- register int j;
- int val;
-
- if (val = _setjmp(errorExitPoint)) {
- /* This means we longjmp to here upon detecting an error */
- ErrMsg("File load error -- request aborted at %d.\n", val);
- /* Clean up (nothing for now) */
- return;
- }
-
- theCode = dotoCodePtr(dotoFilePtr);
- KMDTrace("Code", 3, "Translating Code OID 0x%08x Em version %-15.15s\n",
- theCode->ownOID, 4+ctime(&theCode->emVersion));
-
- /* Phase 3: Translate the OIDs in the file and relocate ref to
- global variables. */
-
- translateDoto(dotoFilePtr);
-
-
- /* Phase 4: Fire up the necessary processes. */
-
- /* Now do the create directives */
- cdPtr = dotoCreateDirectivePtr(dotoFilePtr);
- if (cdPtr->numEntries > 0) {
- KMDTrace("Code", 5, "Firing up processes\n");
- for (j = 0; j < cdPtr->numEntries; j++) {
- SSPtr p;
- GODP theObj;
- CodePtr cPtr = dotoCodePtr(dotoFilePtr);
- KMDTrace("Code", 5, "\t%0.8x\n", cdPtr->createOID[j]);
- theObj = (GODP) OTLookup(cdPtr->createOID[j]);
- if (IsNULL(theObj)){
- ErrMsg("Lookup of created object OID 0x%08x failed\n",
- cdPtr->createOID[j]);
- _longjmp(errorExitPoint, 2);
- }
- if(cPtr->initially.offset) {
- /* Has an initially (InitiallyDone does the process) */
- p = NewProcess();
- StartProcessAtAddr(p, theObj, theObj->dataPtr,
- (CodeAddr) addOffset(cPtr, cPtr->initially.offset));
- } else {
- theObj->tag.setUpDone = TRUE;
- theObj->tag.frozen = FALSE;
- if (cPtr->process.offset) {
- /* No initially, but a process -- fire it up */
- p = NewProcess();
- StartProcessAtAddr(p, theObj, theObj->dataPtr,
- (CodeAddr) addOffset(cPtr, cPtr->process.offset));
- }
- }
- }
- }
-
- /* Phase 5: Declare it done */
- theCode->tag.setUpDone = TRUE;
- theCode->tag.frozen = FALSE;
- theCodeODP = (CodeODP) OTLookup(theCode->ownOID);
- assert(NonNULL(theCodeODP));
- theCodeODP->tag.setUpDone = TRUE;
- theCodeODP->tag.frozen = FALSE;
- }
-
- /**********************************************************************/
-
- void AcceptCode(fLMHandle)
- LMHandle fLMHandle;
- {
- CodeTransferItem item;
- int srcLNN = fLMHandle->mmMsgHdr.MsgSrc;
- int length;
- char *allocedData;
- DotoFilePtr dotoptr;
- ODTag *ptr;
- CodePtr theCode;
- CodeODP myCodeODP;
-
- KMDTrace("Code", 3, "Accepting Code from LNN %d\n", srcLNN);
- length = sizeof(item);
- LMGetData(&fLMHandle, &item, &length);
- assert(length == sizeof(item));
- assert(item.hdr.itemTag == CodeTransferITag);
- length = item.hdr.size - sizeof(item);
- KMDTrace("Code", 4, "Code size is %d bytes.\n", length);
- allocedData = emalloc(length+sizeof(ODTag));
- ptr = (ODTag *) allocedData;
- *ptr = stdDotoODTag;
- dotoptr = (DotoFilePtr) (ptr+1);
- LMGetData(&fLMHandle, dotoptr, &length);
- KMDTrace("Code", 5, "Got %d bytes of code\n", length);
- LMClose(&fLMHandle);
-
- /* Verify validity of code */
- if(!isOkDoto(dotoptr)) {
- ErrMsg(2, "Bad format of code from LNN %d\n", srcLNN);
- emfree(allocedData);
- return;
- }
- theCode = dotoCodePtr(dotoptr);
- KMDTrace("Code", 3, "Code %s\n", PPCOID(theCode->ownOID));
-
- if (theCode->emVersion != EMVERSION) {
- time_t emVersion = EMVERSION;
- ErrMsg("File %s version mismatch in AcceptCode\n");
- ErrMsg("File Em version: %s", ctime(&theCode->emVersion));
- ErrMsg("Kernel version: %s", ctime(&emVersion));
- emfree(allocedData);
- return;
- }
-
- myCodeODP = CreateCodeODEntry(theCode->ownOID, mMakeLocation(srcLNN, 1));
- if (NonNULL((myCodeODP->dataPtr))) {
- KMDTrace("Code", 3, "Already have Code %s\n",
- PPCOID(theCode->ownOID));
- emfree(allocedData);
- return;
- }
- myCodeODP->dataPtr = theCode;
- myCodeODP->ownOID = theCode->ownOID;
- myCodeODP->ownLoc = thisNodeLocation;
- CodeArrived(myCodeODP);
- }
-
- /**********************************************************************/
- /* CheckOnDisk */
- /**********************************************************************/
- Boolean CheckOnDisk(fCTOID)
- OID fCTOID;
- {
- char fileName[200];
- struct stat statBuf;
- int result;
-
- /* Check in /usr/em/EC/Dotos/Objects_%0.1x/OID%08x.o */
- sprintf(fileName, "%sEC/Dotos/Objects_%1.1x/OID%08x.o", EMDIR,
- fCTOID & 0xf, fCTOID);
- KMDTrace("Code", 4, "Checking for %s in %s\n", PPCOID(fCTOID),
- fileName);
- result = stat(fileName, &statBuf);
- if (result < 0) {
- if (errno == ENOENT) {
- KMDTrace("Code", 4, "Not found on disk.\n");
- return FALSE;
- }
- ErrMsg("Code", 2, "Error on stat of %s\n.");
- perror("CheckOnDisk");
- return FALSE;
- }
- KMDTrace("Code", 3, "Found %s on disk.\n", fileName);
- KMDTrace("Code", 4, "Modify time %s", ctime(&statBuf.st_mtime));
- return TRUE;
- }
-
- /**********************************************************************/
- /* LoadFromCompiler */
- /**********************************************************************/
- DotoFilePtr LoadFromCompiler(fCTOID)
- OID fCTOID;
- {
- char fileName[200];
- DotoFilePtr theFile;
- CodeODP theCodeODP;
- CodePtr theCode;
-
- /* Check in /usr/em/EC/Dotos/Objects_%1.1x/OID%08x.o */
- sprintf(fileName, "%sEC/Dotos/Objects_%1.1x/OID%08x.o", EMDIR,
- fCTOID & 0xf, fCTOID);
- KMDTrace("Code", 4, "Trying to load %s from %s\n", PPCOID(fCTOID),
- fileName);
- theFile = readDotoFile(fileName);
- if (IsNULL(theFile)) return theFile;
- theCode = dotoCodePtr(theFile);
- theCodeODP = (CodeODP) OTLookup(fCTOID);
- if (IsNULL(theCodeODP)) {
- /* Create the CodeOD */
- theCodeODP = CreateCodeODEntry(fCTOID, (EmLocation) NULL);
- }
- theCodeODP->dataPtr = theCode;
- theCodeODP->ownOID = theCode->ownOID;
- theCodeODP->ownLoc = thisNodeLocation;
-
- theCode->tag.setUpDone = FALSE;
- theCode->tag.frozen = TRUE;
- theCodeODP->tag.setUpDone = FALSE;
- theCodeODP->tag.frozen = TRUE;
-
- CodeArrived(theCodeODP);
-
- return theFile;
- }
-
- /**********************************************************************/
- /* Loadcheatingfromcompiler */
- /**********************************************************************/
-
- DotoFilePtr LoadCheatingFromCompiler(fObjOID)
- OID fObjOID;
- {
- char fileName[200];
- DotoFilePtr theFile;
- CodeODP theCodeODP;
- CodePtr theCode;
- OID codeOID;
-
- /* Check in /usr/em/EC/Dotos/Objects_%0.1x/OID%08x.o */
- sprintf(fileName, "%sEC/Dotos/Objects_%1.1x/OID%08x.o", EMDIR,
- fObjOID & 0xf, fObjOID);
- KMDTrace("Code", 4, "Trying to load %s from %s\n", PPOID(fObjOID),
- fileName);
- theFile = readDotoFile(fileName);
- if (IsNULL(theFile)) return theFile;
- theCode = dotoCodePtr(theFile);
- codeOID = theCode->ownOID;
- theCodeODP = (CodeODP) OTLookup(codeOID);
- if (IsNULL(theCodeODP)) {
- /* Create the CodeOD */
- theCodeODP = CreateCodeODEntry(codeOID, thisNodeLocation);
- }
- theCodeODP->dataPtr = theCode;
- theCode->tag.setUpDone = FALSE;
- theCode->tag.frozen = TRUE;
- theCodeODP->tag.setUpDone = FALSE;
- theCodeODP->tag.frozen = TRUE;
- theCodeODP->tag.isResident = TRUE;
-
- CodeArrived(theCodeODP);
-
- return theFile;
- }
-
- /**********************************************************************/
- int FLCompilerSockDead()
- {
- ErrMsg("Socket for compiler usage died -- fatal\n");
- abort();
- return 0; /* ought to be void. */
- }
-
- /**********************************************************************/
- void FLUserSockDead(fSock)
- int fSock;
- {
- CompilerLoadReqPtr req;
- EmInStreamPtr inStream;
- EmOutStreamPtr outStream;
-
- KMDTrace("UserIO", 3, "Socket #%d died.\n", fSock);
- req = CReq[fSock];
- if (NonNULL(req)) {
- /* Break streams if necessary */
- if (NonNULL(req->theInStream)) {
- /* Break instream */
- KMDTrace("UserIO", 2, "Instream on socket #%d broke.\n", fSock);
- inStream = (EmInStreamPtr) req->theInStream;
- inStream->isBroken = TRUE;
- req->theInStream = (GODP) NULL;
- CloseInStream(fSock);
- }
- if (NonNULL(req->theOutStream)) {
- /* Break outstream */
- KMDTrace("UserIO", 2, "Outstream on socket #%d broke.\n", fSock);
- outStream = (EmOutStreamPtr) req->theOutStream;
- outStream->isBroken = TRUE;
- req->theOutStream = (GODP) NULL;
- CloseOutStream(fSock);
- }
- }
- CReq[fSock] = (CompilerLoadReqPtr) NULL;
- }
- /**********************************************************************/
- /*ARGSUSED*/
- int FLUserSIGIO(fKind, fSock)
- int fKind;
- int fSock;
- {
- register CompilerLoadReqPtr req;
-
- KMDTrace("UserIO", 3, "UserIO on %d\n", fSock);
- req = CReq[fSock];
- assert(NonNULL(req));
- if (req->status == Connected) {
- SIRemoveSockHandler(fSock, SIREAD);
- HoldSigs();
- QueueTask(ReadCompilerRequest, (char *) req);
- ReleaseSigs();
- } else {
- /* Actual user io */
- KMDTrace("Fix me", 3, "FLUserSIGIO should read from socket\n");
- }
- return 0; /* ought to be declared as void */
- }
-
- /**********************************************************************/
- /* EnsurePresenceOfRequiredTypes */
- /**********************************************************************/
- Boolean EnsurePresenceOfRequiredTypes(fDotoPtr, fReq)
- DotoFilePtr fDotoPtr;
- GenericReqPtr fReq;
- /* Check a doto for references to types that it must have.
- Return TRUE if all done.
- Otherwise return FALSE and enter requests into the wantList */
- {
- register int i;
- long *relocatedAddress;
- RelocationInfoPtr riptr;
- ARelocation ar;
- CodePtr cptr;
- ODP cheatingODP;
- Boolean result = TRUE; /* Assume success */
-
- assert(NonNULL(fDotoPtr));
- cptr = dotoCodePtr(fDotoPtr);
- assert(cptr->tag.tag == CodeTag);
- KMDTrace("Code", 4, "Ensure presence of types required for %s\n",
- PPCOID(cptr->ownOID));
- if (IsNULL(cptr->relocationInfoOffset)) return TRUE;
- riptr = (RelocationInfoPtr) addOffset(cptr, cptr->relocationInfoOffset);
- KMDTrace("Code", 5, "Emerald Relocation numEntries %d\n",
- riptr->numEntries);
- for (i = 0; i < riptr->numEntries; i++) {
- ar = riptr->relocation[i];
- relocatedAddress = (long *) addOffset(cptr, ar.where);
- KMDTrace("Code", 5, "%s: rel loc %d, abs 0x%05x (0x%05x, 0x%05x)\n",
- ar.kind == AR_OIDToODP ? "OIDToODP" :
- ar.kind == AR_OIDToODAP ? "OIDToODAP" :
- ar.kind == AR_OpNumberToAddress ? "OpNumberToAddress" :
- ar.kind == AR_OIDOIDToAbCon ? "OIDOIDToAbCon" :
- ar.kind == AR_OIDToCheatingODP ? "OIDToCheatingODP":
- ar.kind == AR_OIDToCodePtr ? "OIDToCodePtr" :
- "Unknown translation",
- ar.where, relocatedAddress, ar.theOID1, ar.theOID2);
- switch (ar.kind) {
- case AR_OIDToODP:
- /* Do not need the CT */
- break;
- case AR_OIDToODAP:
- /* Immutable object, need CT, must create obj later */
- result = LoadRequest(ar.theOID2, fReq) && result;
- break;
- case AR_OpNumberToAddress:
- /* Do not need to have it */
- break;
- case AR_OIDOIDToAbCon:
- /* Need AT */
- result = LoadRequest(ar.theOID1, fReq) && result;
- break;
- case AR_OIDToCheatingODP:
- /* Need CT */
- result = LoadRequest(ar.theOID2, fReq) && result;
- /* Start a location of the object.
- The translation stuff will either crank up the
- object or use the remote object. */
- cheatingODP = OTLookup(ar.theOID1);
- if (IsNULL(cheatingODP)) {
- cheatingODP = (ODP) CreateGODEntry(ar.theOID1, ar.theOID2);
- }
- if (!cheatingODP->G.tag.isResident) {
- /* The object is not here, so locate it */
- StartLocate(fReq, cheatingODP);
- result = FALSE;
- }
- break;
- case AR_OIDToCodePtr:
- /* Need CT */
- result = LoadRequest(ar.theOID1, fReq) && result;
- break;
- default:
- ErrMsg("Bad translation kind %d\n", ar.kind);
- assert(FALSE);
- break;
- }
- }
- return result;
- }
- /**********************************************************************/
-
- /**********************************************************************/
- /* SendCode */
- /**********************************************************************/
-
- void SendCode(fODP, fLNN)
- CodeODP fODP;
- NodeNum fLNN;
- /* Send the Code given by OID to the node given by fLNN */
- /* Note: OID is represented as ASCII */
- {
- register CodeODP theCodeODP = fODP;
- OID theCodeOID = fODP->ownOID;
- LMHandle myLMHandle;
- CodeTransferItem item;
- HOTSRecord *hotsPtr;
- DotoFilePtr dotoptr;
-
- KMDTrace("Code", 3, "Sending Code %s to node #%d\n", PPCOID(theCodeOID),
- fLNN);
- if ((!mSUCCESS(HOTSSearchPtr(fLNN, &hotsPtr))) || (hotsPtr->NodeStat !=
- Alive) && (hotsPtr->NodeStat != Booting)) {
- KMDTrace("Code", 2, "Node %d down, SendCode(%s) ignored.\n", fLNN,
- PPCOID(fODP->ownOID));
- return;
- }
- dotoptr = (DotoFilePtr)
- addOffset(theCodeODP->dataPtr, -sizeof(dotoptr->header));
- LMStartMsg(&myLMHandle, KMSG_EmKernel, EMKM_FLAcceptCode, fLNN);
- item.hdr.itemTag = CodeTransferITag;
- item.hdr.size = N_STROFF(dotoptr->header) +
- ( * ( (int *)addOffset(dotoptr, N_STROFF(dotoptr->header) ) ) ) +
- sizeof(ItemHdr);
- LMPutData(&myLMHandle, &item, sizeof(item));
- LMPutData(&myLMHandle, dotoptr, item.hdr.size - sizeof(item));
- if (!mSUCCESS(LMSendMsg(&myLMHandle))) {
- KMDTrace("Code", 3,
- "Cannot send msg to node %d, SendCode(%s) ignored.\n", fLNN,
- PPCOID(fODP->ownOID));
- }
- }
-
-
- /**********************************************************************/
- /* RemoteLoadItemHandler */
- /**********************************************************************/
- void RemoteLoadItemHandler(fHandlePtr, fHdr)
- LMHandlePtr fHandlePtr;
- ItemHdr fHdr;
- {
- int length;
- OID theOID;
- CodeODP theODP;
- DotoFilePtr doto;
-
- KMDTrace("Code", 5, "Remote Load request arrived\n");
- assert(fHdr.size == sizeof(RemoteLoadReqItem));
- length = sizeof(theOID);
- LMGetData(fHandlePtr, &theOID, &length);
- assert(length == sizeof(theOID));
- theODP = (CodeODP) OTLookup(theOID);
- if (NonNULL(theODP) && NonNULL(theODP->dataPtr)) {
- SendCode(theODP, (*fHandlePtr)->mmMsgHdr.MsgSrc);
- } else if (((((unsigned int) theOID) >> 24) & 0xFF) == 0xFF) {
- /* Trying in compiler directory */
- doto = LoadFromCompiler(theOID);
- if (IsNULL(doto)) {
- KMDTrace("Code", 5, "Did not find %s on disk\n", PPOID(theOID));
- } else {
- theODP = (CodeODP) OTLookup(theOID);
- assert(NonNULL(theODP));
- KMDTrace("Code", 3, "Found %s on disk.\n");
- SendCode(theODP, (*fHandlePtr)->mmMsgHdr.MsgSrc);
- }
- }
- }
-
- /**********************************************************************/
- /* RemoteLoadDeamon */
- /**********************************************************************/
- void RemoteLoadDeamon()
- {
- CodeLoadReqPtr req;
- RemoteLoadReqItem item;
- OID theOID;
- CodeODP theODP;
- Boolean started = FALSE;
- LMHandle myHandle;
- int nodeLNN;
-
- KMDTrace("Code", 5, "RemoteLoadDeamon\n");
- KMDTrace("FixMe", 3, "(RemoteLoadDeamon should batch req together.)1\n");
- Map_For(RemoteLoadMap, theOID, req)
- if (req->status == FoundSomewhere) {
- req->status = LoadRequested;
- theODP = (CodeODP) OTLookup(req->theCodeOID);
- assert(NonNULL(theODP));
- KMDTrace("Code", 3,
- "Issuing remote load request for %s at 0x%04x\n",
- PPCOID(theOID), theODP->ownLoc);
- nodeLNN = mGetLocNodeNum(theODP->ownLoc);
- if(IsNULL(nodeLNN)) {
- ErrMsg("Remote load request for %s to unknown node #%d\n",
- PPCOID(theODP->ownOID), nodeLNN);
- continue;
- }
- if(!started) {
- started = TRUE;
- LMStartMsg(&myHandle, KMSG_EmKernel, EMKM_Item, nodeLNN);
- }
- item.hdr.itemTag = RemoteLoadReqITag;
- item.hdr.size = sizeof(item);
- item.theOID = theOID;
- LMPutData(&myHandle, &item, sizeof(item));
- if (started) {
- LMSendMsg(&myHandle);
- started = FALSE;
- }
- }
- Map_Next
- RemoteLoadDeamonRunning = FALSE;
- }
-
- /**********************************************************************/
- /* EnsureRemoteLoadDeamon */
- /**********************************************************************/
- void EnsureRemoteLoadDeamon()
- /* Ensure that a deamon is running which regularily performs remote
- load requests. Such requests are deferred many milliseconds as to
- get them batched together.
- */
- {
- if (!RemoteLoadDeamonRunning) {
- KMDTrace("Code", 5, "Scheduling RemoteLoad Deamon\n");
- RemoteLoadDeamonRunning = TRUE;
- (void) MMSetMicroTimer(vFLRemoteLoadDeamonInterval/1000000,
- vFLRemoteLoadDeamonInterval % 1000000, RemoteLoadDeamon, NULL,
- NULL);
- }
- }
-
- /**********************************************************************/
- /* EnsureLoadOfATs */
- /**********************************************************************/
- Boolean EnsureLoadOfATs(fReq, fCodeODP)
- GenericReqPtr fReq;
- CodeODP fCodeODP;
- {
- Boolean gotItAll = TRUE;
- AbConPtr theAbConPtr;
-
- if (IsNULL(fCodeODP) || (IsNULL(fCodeODP->AbConSetPtr)) ||
- Set_Count((Set) fCodeODP->AbConSetPtr) == 0
- ) {
- return TRUE;
- }
-
- Set_For((Set) fCodeODP->AbConSetPtr, theAbConPtr)
- KMDTrace("Code", 5, "Checking abcon @ 0x%04x\n", theAbConPtr);
- KMDTrace("AbCon", 5, "Checking abcon @ 0x%04x\n", theAbConPtr);
- if (IsNULL(theAbConPtr)) {
- KMDTrace("AbCon", 4, "Must load AT: %s for abcon (0x%04x)\n",
- PPCOID(theAbConPtr->ATOID), theAbConPtr);
- gotItAll = LoadRequest(theAbConPtr->ATOID, fReq) && gotItAll;
- }
- Set_Next
- return gotItAll;
- }
-
- /**********************************************************************/
- /* CodeLoadCallBack */
- /**********************************************************************/
- void CodeLoadCallBack(fReq, fCTOID)
- CodeLoadReqPtr fReq;
- OID fCTOID;
- /* Invoked when a state change occurs for a pending load request, e.g.,
- code arrives from another node, the code has been located on another
- node, etc. */
- {
- register CodeLoadReqPtr req = fReq;
-
- KMDTrace("Code", 4, "CodeLoadCallBack for %s, status %s, OID:%s\n",
- PPCOID(req->theCodeOID),
- req->status == DoNotKnow ? "Location not known" :
- req->status == FoundSomewhere ? "Located" :
- req->status == LoadRequested ? "Load requested" :
- req->status == Transferred ? "Code transferred to here" :
- req->status == Translated ? "Code load done":
- "BAD STATUS",
- PPCOID(fCTOID));
-
- /*
- * The following switch statement may be confusing:
- * The status switched upon is the old status - not the new status
- */
-
- switch (req->status) {
-
- case DoNotKnow:{
- CodeODP theCodeODP;
- CodePtr codePtr;
- int nodeLNN;
-
- /* The Code has now been found somewhere */
- req->status = FoundSomewhere;
-
-
- theCodeODP = (CodeODP) OTLookup(req->theCodeOID);
-
- nodeLNN = mGetLocNodeNum(theCodeODP->ownLoc);
- if(IsNULL(nodeLNN)) { /* Did not find it */
- Map_Delete(CodeLoadMap, (int) req->theCodeOID);
- DoCallBack((GenericReqPtr) req, (OID) NULL);
- FreeRequest((GenericReqPtr) req);
- break;
- }
-
- /* Issue a remote load request */
- Map_Insert(RemoteLoadMap, (int) req->theCodeOID, (int) req);
- EnsureRemoteLoadDeamon();
- break;
- }
-
- case LoadRequested:
- case FoundSomewhere: {
- CodeODP theCodeODP;
- CodePtr codePtr;
- DotoFilePtr doto;
-
- theCodeODP = (CodeODP) OTLookup(req->theCodeOID);
- assert(NonNULL(theCodeODP));
- codePtr = theCodeODP->dataPtr;
- if (IsNULL(codePtr)) {
- ErrMsg("Could not find code %s -- request now hung.\n",
- PPCOID(codePtr->ownOID));
- return;
- }
- doto = mDotoFilePtrFromCodePtr(codePtr);
- req->status = Transferred;
- /* Now fetch all needed types */
- if (!EnsurePresenceOfRequiredTypes(doto, (GenericReqPtr) req)) {
- KMDTrace("Code", 4, "Load of %s must await other loads\n",
- PPCOID(req->theCodeOID));
- return;
- }
- if (!EnsureLoadOfATs((GenericReqPtr) req, theCodeODP)) {
- KMDTrace("Code", 4, "Load of %s must await load of ATs\n",
- PPCOID(req->theCodeOID));
- KMDTrace("AbCon", 4, "Load of %s must await load of ATs\n",
- PPCOID(req->theCodeOID));
- return;
- }
- /* NBNB: No break here ! */
- fCTOID = (OID) NULL; /* since we are falling through to Transferred */
- }
-
- case Transferred: {
- CodeODP theCodeODP;
- CodePtr theCode;
- DotoFilePtr doto;
-
- /* We now have another of the required types loaded (given by fCTOID)
- check to see, if we are done */
- if (Map_Count(req->hdr.wantList) == 0) {
-
- theCodeODP = (CodeODP) OTLookup(req->theCodeOID);
- assert(NonNULL(theCodeODP));
- /*
- * Now we think that we are done but have to check for ATs to
- * load since there may be AbCons out there that absolutely need
- * to be redone.
- */
-
- if (!EnsureLoadOfATs((GenericReqPtr) req, theCodeODP)) {
- KMDTrace("Code", 4, "Load of %s must await load of ATs\n",
- PPCOID(req->theCodeOID));
- KMDTrace("AbCon", 4, "Load of %s must await load of ATs\n",
- PPCOID(req->theCodeOID));
- break;
- }
-
- /* Got them all */
- KMDTrace("Code", 4, "All required types for %s are now loaded\n",
- PPCOID(req->theCodeOID));
- theCode = theCodeODP->dataPtr;
- doto = mDotoFilePtrFromCodePtr(theCode);
- translateDoto(doto);
- theCodeODP->tag.setUpDone = TRUE;
- theCodeODP->tag.frozen = FALSE;
- theCodeODP->ownLoc = thisNodeLocation;
- theCode->tag.setUpDone = TRUE;
- theCode->tag.frozen = FALSE;
- KMDTrace("Code", 3, "%s now fully loaded and done\n",
- PPCOID(theCodeODP->ownOID));
- Map_Delete(CodeLoadMap, (int) req->theCodeOID);
- DoCallBack((GenericReqPtr) req, req->theCodeOID);
- FreeRequest((GenericReqPtr) req);
- break;
- }
- KMDTrace("Code", 4, "Got %s for %s but still need more\n",
- PPCOID(req->theCodeOID), PPCOID(fCTOID));
- break;
- }
-
- case Translated: {
- break;
- }
- default: assert(FALSE);
- }
- }
-
- /**********************************************************************/
- /* LoadRequest */
- /**********************************************************************/
-
- Boolean LoadRequest(fCTOID, fReq)
- OID fCTOID;
- GenericReqPtr fReq;
- /*
- Load the specified code; if necessary, crank up a CodeLoad Request
- and enter it into the want list of fReq.
- Return TRUE, if load completed, otherwise return FALSE after
- cranking up the CodeLoad Request */
- {
- register CodeLoadReqPtr req;
- CodeODP theCodeODP;
- CodePtr theCode;
- DotoFilePtr doto;
-
- KMDTrace("Code", 4, "LoadRequest for %s\n", PPCOID(fCTOID));
- assert(fCTOID != (OID) NULL);
- theCodeODP = (CodeODP) OTLookup(fCTOID);
- if (IsNULL(theCodeODP)) {
- /* Create a CodeOD, location unknown */
- theCodeODP = CreateCodeODEntry(fCTOID, (EmLocation) NULL);
- }
-
- if (theCodeODP->tag.setUpDone) {
- /* It is there and ready, so we are done */
- KMDTrace("Code", 4, "Need and have %s\n", PPCOID(fCTOID));
- return TRUE;
- }
- req = (CodeLoadReqPtr) Map_Lookup(CodeLoadMap, (int) fCTOID);
- if ((int) req != EMNIL) {
- /* A load request for the CTOID already exists */
- if ((req->status == Transferred) || (req->status == Translated)) {
- /* We know enough to translated it so continue */
- /* (This happens, e.g., if the code refers to itself.) */
- KMDTrace("Code", 4,
- "Got %s loaded enough to use it for translation.\n",
- PPCOID(fCTOID));
- return TRUE;
- }
- if ( Map_Lookup(fReq->hdr.wantList, (int) req) != (int) EMNIL) {
- /* It is already in our want list so return */
- KMDTrace("Code", 4, "Already want %s\n", PPCOID(fCTOID));
- return FALSE;
- }
- /* He needs it, so put it into his want list */
- Map_Insert(req->hdr.reqBy, (int) fReq, 0);
- Map_Insert(fReq->hdr.wantList, (int) req, 0);
- KMDTrace("Code", 3, "%s load in progress; add it to the want list\n",
- PPCOID(fCTOID));
- return FALSE;
- }
- req = mNewRequest(CodeLoad);
- req->theCodeOID = fCTOID;
- req->hdr.callBack = (GenericHandlerPtr) CodeLoadCallBack;
- req->status = DoNotKnow;
- KMDTrace("Code", 4, "Crank up load request for %s\n", PPCOID(fCTOID));
- Map_Insert(CodeLoadMap, (int) fCTOID, (int) req);
- Map_Insert(req->hdr.reqBy, (int) fReq, 0);
- Map_Insert(fReq->hdr.wantList, (int) req, 0);
-
- if (IsNULL(theCodeODP->dataPtr)) {
- /* We do not have the code, try the compiler directory */
- doto = LoadFromCompiler(fCTOID);
- if (NonNULL(doto)) {
- KMDTrace("Code", 3, "Found %s in the compiler directory\n",
- PPCOID(fCTOID));
- }
- } else {
- doto = mDotoFilePtrFromCodePtr(theCodeODP->dataPtr);
- }
-
- if (NonNULL(theCodeODP->dataPtr)) {
- req->status = Transferred;
- if (!EnsureLoadOfATs(fReq, theCodeODP)) {
- KMDTrace("Code", 5, "Need some ATs for AbCons\n");
- } else if (EnsurePresenceOfRequiredTypes(doto, (GenericReqPtr) req)) {
- /* They are all there, now translate and activate any processes */
- KMDTrace("Code", 4, "All required types for %s loaded\n",
- PPCOID(fCTOID));
- translateDoto(doto);
- theCodeODP->tag.setUpDone = TRUE;
- theCodeODP->tag.frozen = FALSE;
- theCodeODP->ownLoc = thisNodeLocation;
- theCode = theCodeODP->dataPtr;
- theCode->tag.setUpDone = TRUE;
- theCode->tag.frozen = FALSE;
- Map_Delete(CodeLoadMap, (int) fCTOID);
- Map_Delete(req->hdr.reqBy, (int) fReq);
- Map_Delete(fReq->hdr.wantList, (int) req);
- FreeRequest((GenericReqPtr) req);
- KMDTrace("Code", 2, "%s fully loaded and done\n", PPCOID(fCTOID));
- return TRUE;
- }
- }
- KMDTrace("Code", 3, "Must wait for %s to be found and loaded\n",
- PPCOID(fCTOID));
- StartLocate((GenericReqPtr) req, (ODP) theCodeODP);
- return FALSE;
- }
-
- /**********************************************************************/
- /* DoCompilerCreate */
- /**********************************************************************/
-
- void DoCompilerCreate(fReq, fOID)
- register CompilerLoadReqPtr fReq;
- OID fOID;
- /* Callback routine for compiler creation */
- {
- CodeODP theCodeODP;
- CodePtr theCode;
- GODP createdODP;
-
- KMDTrace("Code", 3,
- "Callback after loading code; creating object one of %s\n",
- PPGOID(fReq->createdCTOID));
-
- if (fReq->createdCTOID != fOID || IsNULL(fOID) ||
- IsNULL(OTLookup(fOID))) /* rather safe than sorry */
- {
- char *badprog = "Emerald program not found (try recompiling)\n";
- int length = strlen(badprog);
- int count;
-
- KMDTrace("Code", 2, "CTOID %s not found, abort request\n",
- PPCOID(fReq->createdCTOID));
- KMDTrace("Failure", 3, "CTOID %s not found, abort request\n",
- PPCOID(fReq->createdCTOID));
-
- count = write(fReq->sock, badprog, length);
- if (count < 0) {
- ErrMsg("Couldn't write err msg to user in DoCompileCreate\n");
- perror("DoCompileCreate");
- }
- /* Close the connection to runec */
- CReq[fReq->sock] = (CompilerLoadReqPtr) NULL;
- SIRemoveSockHandler(fReq->sock, SIREAD);
- SIRemoveSockHandler(fReq->sock, SIEXCEPT);
- (void) close(fReq->sock);
- FreeRequest((GenericReqPtr) fReq);
- return;
- }
-
- if (fReq->hangAround) {
- /* Create streams */
- MakeStreamsFromSock(fReq->sock, &fReq->theInStream,
- &fReq->theOutStream);
- } else {
- /* Use kernel std in/out */
- fReq->theInStream = kernelStdInStream;
- fReq->theOutStream = kernelStdOutStream;
- /* Close the connection to runec */
- CReq[fReq->sock] = (CompilerLoadReqPtr) NULL;
- SIRemoveSockHandler(fReq->sock, SIREAD);
- SIRemoveSockHandler(fReq->sock, SIEXCEPT);
- (void) close(fReq->sock);
- };
-
- assert(fOID == fReq->createdCTOID);
- theCodeODP = (CodeODP) OTLookup(fReq->createdCTOID);
- theCode = theCodeODP->dataPtr;
- fReq->status = Translating;
- createdODP = AllocateWithOID(theCode, (OID) NULL,
- theCode->instanceSize);
- fReq->createdObj = createdODP;
- if (!fReq->hangAround) {
- Map_Delete(CompilerLoadMap, (int) fReq);
- FreeRequest((GenericReqPtr) fReq);
- }
- KMDTrace("Code", 2, "Created one of %s\n", PPCOID(fReq->createdCTOID));
- if(theCode->initially.offset) {
- SSPtr p;
- /* Has an initially (InitiallyDone does the process) */
- KMDTrace("Code", 3, "Starting its initially.\n");
- p = NewProcess();
- StartProcessAtAddr(p, createdODP, createdODP->dataPtr,
- (CodeAddr) addOffset(theCode, theCode->initially.offset));
- } else {
- createdODP->tag.setUpDone = TRUE;
- createdODP->tag.frozen = FALSE;
- if (theCode->process.offset) {
- SSPtr p;
- /* No initially, but a process -- fire it up */
- KMDTrace("Code", 3, "Starting its process\n");
- p = NewProcess();
- StartProcessAtAddr(p, createdODP, createdODP->dataPtr,
- (CodeAddr) addOffset(theCode, theCode->process.offset));
- }
- }
- }
-
- /**********************************************************************/
- /* ReadCompilerRequest */
- /**********************************************************************/
-
- void ReadCompilerRequest(fReq)
- register CompilerLoadReqPtr fReq;
- /* Called to read the compiler request info and start the desired object */
- {
- char buf[17], hangAround;
- OID ctOID;
- int count, n;
- CodeODP theCodeODP;
- CodePtr theCode;
- GODP createdODP;
-
- count = recv(fReq->sock, buf, 16, 0);
- buf[16] = (char) 0;
- if (count != 16) {
- ErrMsg("Bad msg on compiler socket");
- if (count < 0) perror("ReadCompilerRequest");
- return;
- }
-
- KMDTrace("Code", 3, "Program load request %-11.11s\n", buf);
- n = sscanf(buf, "0x%8x%c", &ctOID, &hangAround);
- if (n != 2) {
- ErrMsg("Compiler request bad format: %s\n", buf);
- (void) close(fReq->sock);
- return;
- }
-
- fReq->hangAround = (hangAround == 'T');
- fReq->status = Loading;
- fReq->createdCTOID = ctOID;
- fReq->hdr.callBack = (GenericHandlerPtr) DoCompilerCreate;
- if (LoadRequest(ctOID, (GenericReqPtr) fReq)) {
- if (fReq->hangAround) {
- /* Create streams */
- MakeStreamsFromSock(fReq->sock, &fReq->theInStream,
- &fReq->theOutStream);
- } else {
- /* Use kernel std in/out */
- fReq->theInStream = kernelStdInStream;
- fReq->theOutStream = kernelStdOutStream;
- /* Close the connection to runec */
- CReq[fReq->sock] = (CompilerLoadReqPtr) NULL;
- SIRemoveSockHandler(fReq->sock, SIREAD);
- SIRemoveSockHandler(fReq->sock, SIEXCEPT);
- (void) close(fReq->sock);
- };
- theCodeODP = (CodeODP) OTLookup(ctOID);
- theCode = theCodeODP->dataPtr;
- fReq->status = Translating;
- createdODP = AllocateWithOID(theCode, (OID) NULL,
- theCode->instanceSize);
- fReq->createdObj = createdODP;
- if (!fReq->hangAround) {
- Map_Delete(CompilerLoadMap, (int) fReq);
- FreeRequest((GenericReqPtr) fReq);
- }
- KMDTrace("Code", 2, "Created one of %s\n", PPCOID(ctOID));
- if(theCode->initially.offset) {
- SSPtr p;
- /* Has an initially (InitiallyDone does the process) */
- KMDTrace("Code", 3, "Starting initially for one of %s\n",
- PPCOID(ctOID));
- p = NewProcess();
- StartProcessAtAddr(p, createdODP, createdODP->dataPtr,
- (CodeAddr) addOffset(theCode, theCode->initially.offset));
- } else {
- createdODP->tag.setUpDone = TRUE;
- createdODP->tag.frozen = FALSE;
- if (theCode->process.offset) {
- SSPtr p;
- /* No initially, but a process -- fire it up */
- KMDTrace("Code", 3, "Starting its process\n");
- p = NewProcess();
- StartProcessAtAddr(p, createdODP, createdODP->dataPtr,
- (CodeAddr) addOffset(theCode, theCode->process.offset));
- }
- }
- }
- }
-
- /**********************************************************************/
- /* FLNewRequest */
- /**********************************************************************/
-
- int FLNewRequest()
- /* A sigio has arrived for the compiler socket, so empty out all the
- * connection requests it.
- * (Note, this procedure ought to be declared void since it does not
- * return any value.)
- */
- {
- register CompilerLoadReqPtr req;
- int newReqSock;
- int reqSrcLength;
- struct sockaddr_in reqSrc; /* for lint, use sockaddr */
-
- while(1) {
- reqSrcLength = sizeof(reqSrc);
- newReqSock = accept(CompilerSock, (struct sockaddr *) &reqSrc,
- &reqSrcLength);
- if (newReqSock < 0) {
- KMDTrace("Code", 6, "No more compiler request\n");
- if (errno == EWOULDBLOCK) return 0;
- ErrMsg("Bad status from accept %d\n", errno);
- perror("FLNewRequest");
- } else {
- /* Accept and set up a new request */
- KMDTrace("UserIO", 3, "New connection, socket #%d\n", newReqSock);
-
- /* Clean out the socket */
- KMDTrace("FixMe", 3, "Need to clean out socket\n");
-
- /* Make the request line use SIGIO */
- if (fcntl(newReqSock, F_SETFL, FASYNC | FNDELAY) < 0 ) {
- perror("newReqSock: fcntl");
- return 0; /* ought to be declared as void */
- };
-
- if (fcntl(newReqSock, F_SETOWN, getpid()) < 0 ) {
- perror("newReqSock: fcntl");
- return 0; /* should be void */
- };
-
- SISetSockHandler(newReqSock, SIREAD, (SIHandlerPtr) FLUserSIGIO);
- SISetSockHandler(newReqSock, SIEXCEPT,
- (SIHandlerPtr) FLUserSockDead);
- /* Ensure that a SIGIO occurs soon (there might already be input
- available on the socket) */
- SIEnsureSIGIO();
-
- /* Put into request list and sooner or later something will
- arrive (or the connection will die).
- */
-
- KMDTrace("Code", 3, "Program load connection request\n");
-
- req = mNewRequest(CompilerLoad);
- req->sock = newReqSock;
- req->status = Connected;
- req->createdObj = (GODP) NULL;
- req->waitingRead =
- req->waitingWrite = (SSPtr) NULL;
- CReq[newReqSock] = req;
- Map_Insert(CompilerLoadMap, (int) req, 0);
- }
- }
- }
-
- /* Forward */ int StreamInputSIGIO();
-
- /**********************************************************************/
- /* StreamInput */
- /**********************************************************************/
- void StreamInput(fSock)
- int fSock;
- /* The socket has become available for input */
- {
- int sock, i, count, length;
- VectorPtr vector;
- SSPtr theProcess;
- register CompilerLoadReqPtr req;
-
- KMDTrace("UserIO", 3, "StreamInput on socket %d\n", fSock);
- sock = fSock;
-
- for (i=0; i < 32 && (IsNULL(CReq[i]) || CReq[i]->sock != sock); i++);
-
- if (i == 32) {
- KMDTrace("UserIO", 1, "StreamInput found socket #%d disconnected\n",
- sock);
- return;
- }
- req = CReq[i];
- sock = req->sock;
- length = req->lengthRead;
- vector = req->vectorRead;
-
- /* Attempt to read */
- count = read(sock, (char *) &vector->data[0], length);
- KMDTrace("UserIO", 5, "Read returned %d bytes\n", count);
-
- if (count < 0) {
- if (errno == EWOULDBLOCK) {
- KMDTrace("UserIO", 2, "StreamInput found no data\n");
- SISetSockHandler(sock, SIREAD, (SIHandlerPtr) StreamInputSIGIO);
- return;
- }
- KMDTrace("UserIO", 3, "Read error %d\n", errno);
- perror("StreamRead");
- /* Should cleanup socket */
- fail(req->waitingRead);
- req->waitingRead = (SSPtr) NULL;
- req->vectorRead = (VectorPtr) NULL;
- return;
- }
- theProcess = req->waitingRead;
- theProcess->resultBrand = DataBrand;
- theProcess->regs.arg1 = count - 1; /* supposed to return maxValidIndex */
- req->waitingRead = (SSPtr) NULL;
- req->vectorRead = (VectorPtr) NULL;
- schedule(theProcess);
- if (count == 0) {
- CloseInStream(sock);
- }
- }
-
- /**********************************************************************/
- /* StreamInputSIGIO */
- /**********************************************************************/
- /*ARGSUSED*/
- int StreamInputSIGIO(fKind, fSock)
- int fKind, fSock;
- {
- SIRemoveSockHandler(fSock, SIREAD);
- HoldSigs();
- QueueTask(StreamInput, (char *) fSock);
- ReleaseSigs();
- return 0; /* ought to be delcared as void */
- }
-
- /**********************************************************************/
- /* StreamRead */
- /**********************************************************************/
-
- /*Kernel Call */
- void StreamRead(fSock, fCharVector)
- int fSock;
- GODP fCharVector;
- /* Asynchronously read from the socket returning up to fCharVector.upb
- characters in fCharVector */
- {
- int sock, i, count, length;
- VectorPtr vector;
- SSPtr theProcess;
- register CompilerLoadReqPtr req;
- AbConPtr charVectorAbCon;
-
- theProcess = preemptRunning();
-
- sock = fSock;
-
- KMDTrace("UserIO", 4, "StreamRead, sock = %d in %s\n", fSock,
- PPSSPlace(theProcess));
-
- for (i=0; i < 32 && (IsNULL(CReq[i]) || CReq[i]->sock != sock); i++);
-
- if (i == 32) {
- KMDTrace("UserIO", 2, "Read attempt on disconnect socket #%d\n",sock);
- fail(theProcess);
- return;
- }
- req = CReq[i];
-
- if (fCharVector == (GODP) EMNIL) {
- KMDTrace("UserIO", 2, "Char vector is NIL in StreamRead.\n");
- fail(theProcess);
- return;
- }
-
- if (!fCharVector->tag.isResident) {
- KMDTrace("UserIO", 2, "Char vector is non-resident.\n");
- charVectorAbCon = OIDOIDOIDToAbCon(
- fCharVector->dataPtr->myCodePtr->ownAbstractType,
- OIDOfBuiltin(B_INSTAT, ANYINDEX),
- fCharVector->dataPtr->myCodePtr->ownOID);
- unavail(theProcess, fCharVector, charVectorAbCon);
- return;
- }
-
- if (fCharVector->tag.global) {
- vector = (VectorPtr) fCharVector->dataPtr;
- } else vector = (VectorPtr) fCharVector;
-
- length = vector->upb+1;
- if (length <= 0) {
- KMDTrace("UserIO", 2,
- "Char vector length is not postive in StreamRead.\n");
- fail(theProcess);
- return;
- }
-
- /* Check for other readers */
- if (NonNULL(req->waitingRead)) {
- KMDTrace("UserIO", 2, "Read socket busy.\n");
- fail(theProcess);
- return;
- }
-
- /* Attempt to read */
- count = read(sock, (char *) &vector->data[0], length);
- KMDTrace("UserIO", 5, "Read returned %d bytes\n", count);
-
- if (count < 0) {
- if (errno == EWOULDBLOCK) {
- KMDTrace("UserIO", 3, "StreamRead blocking %s at %s\n",
- PPPOID(theProcess->processOID), PPSSPlace(theProcess));
- req->vectorRead = vector;
- req->lengthRead = length;
- req->waitingRead = theProcess;
- theProcess->status.rs = SSReadIOWait;
- KMDTrace("LineNumber", 3, "%s blocking on i/o read in %s\n",
- PPPOID(theProcess->processOID), PPSSPlace(theProcess));
- SISetSockHandler(req->sock, SIREAD,
- (SIHandlerPtr) StreamInputSIGIO);
- return;
- }
- KMDTrace("UserIO", 3, "Read error %d\n", errno);
- perror("StreamRead");
- /* Should cleanup socket */
- KMDTrace("FixMe", 3, "Should clean out socket #%d\n", sock);
- fail(theProcess);
- return;
- }
- theProcess->resultBrand = DataBrand;
- theProcess->regs.arg1 = count - 1; /* supposed to return maxvalidindex */
- schedule(theProcess);
- if (count == 0) {
- CloseInStream(sock);
- }
- }
-
- /**********************************************************************/
- /* StreamOutput */
- /**********************************************************************/
- void StreamOutput(fSock)
- int fSock;
- /* The socket has become writable, now try writing on it. */
- {
- int sock, i, count, length;
- VectorPtr vector;
- SSPtr theProcess;
- register CompilerLoadReqPtr req;
-
- KMDTrace("UserIO", 3, "StreamOutput on socket %d\n", fSock);
- sock = fSock;
-
- for (i=0; i < 32 && (IsNULL(CReq[i]) || CReq[i]->sock != sock); i++);
-
- if (i == 32) {
- KMDTrace("UserIO", 2, "StreamOutput found stream #%d disconnected\n",
- sock);
- return;
- }
- req = CReq[i];
- length = req->lengthWrite;
- vector = req->vectorWrite;
- assert(NonNULL(req->waitingWrite));
-
- /* Attempt to write */
- count = write(sock, (char *) &vector->data[0], length);
- KMDTrace("UserIO", 5, "Write returned %d bytes\n", count);
-
- if (count < 0) {
- if (errno == EWOULDBLOCK) {
- KMDTrace("UserIO", 3, "StreamOutput would block\n");
- return;
- }
- KMDTrace("UserIO", 1, "Write error %d\n", errno);
- perror("StreamOutput");
- /* Should cleanup socket */
- fail(req->waitingWrite);
- req->waitingWrite = (SSPtr) NULL;
- req->vectorWrite = (VectorPtr) NULL;
- return;
- }
- theProcess = req->waitingWrite;
- req->waitingWrite = (SSPtr) NULL;
- req->vectorWrite = (VectorPtr) NULL;
- theProcess->resultBrand = DataBrand;
- theProcess->regs.arg1 = count;
- schedule(theProcess);
- }
-
- /**********************************************************************/
- /* StreamOutputSIGIO */
- /**********************************************************************/
- /*ARGSUSED*/
- int StreamOutputSIGIO(fKind, fSock)
- int fKind, fSock;
- {
- SIRemoveSockHandler(fSock, SIWRITE);
- HoldSigs();
- QueueTask(StreamOutput, (char *) fSock);
- ReleaseSigs();
- }
-
- /**********************************************************************/
- /* StreamWrite */
- /**********************************************************************/
-
- /* Kernel call */
- void StreamWrite(fSock, fCharVector, fCount)
- int fSock;
- GODP fCharVector;
- int fCount;
- {
- int sock, i, count, length;
- VectorPtr vector;
- register CompilerLoadReqPtr req;
- AbConPtr charVectorAbCon;
-
- sock = fSock;
-
- KMDTrace("UserIO", 3, "StreamWrite on socket #%d\n", sock);
-
- for (i=0; i < 32 && (IsNULL(CReq[i]) || CReq[i]->sock != sock); i++);
- if (i == 32) {
- KMDTrace("UserIO", 2, "Write attempt on disconnect socket #%d\n",
- sock);
- fail(preemptRunning());
- return;
- }
- req = CReq[i];
-
- if (fCharVector == (GODP) EMNIL) {
- KMDTrace("UserIO", 2, "Char vector is NIL in StreamWrite.\n");
- fail(preemptRunning());
- return;
- }
-
- if (!fCharVector->tag.isResident) {
- KMDTrace("UserIO", 2, "Char vector is non-resident.\n");
- charVectorAbCon = OIDOIDOIDToAbCon(
- fCharVector->dataPtr->myCodePtr->ownAbstractType,
- OIDOfBuiltin(B_INSTAT, ANYINDEX),
- fCharVector->dataPtr->myCodePtr->ownOID);
- unavail(preemptRunning(), fCharVector, charVectorAbCon);
- return;
- }
-
- if (fCharVector->tag.global) {
- vector = (VectorPtr) fCharVector->dataPtr;
- } else vector = (VectorPtr) fCharVector;
-
- length = vector->upb+1;
- if (length <= 0) {
- KMDTrace("UserIO", 2,
- "Char vector length is not postive in StreamWrite.\n");
- fail(preemptRunning());
- return;
- }
-
- if (length < fCount) {
- KMDTrace("UserIO", 2,
- "Char vector too short in StreamWrite.\n");
- fail(preemptRunning());
- return;
- }
-
- /* Check for other writers */
- if (NonNULL(req->waitingWrite)) {
- KMDTrace("UserIO", 2, "Another process is writing on socket.\n");
- fail(preemptRunning());
- return;
- }
-
- /* Attempt to write */
- count = write(sock, (char *) &vector->data[0], fCount);
- KMDTrace("UserIO", 5, "Write returned %d byte%s\n", count,
- mPLURAL(count));
-
- if (count < 0) {
- if (errno == EWOULDBLOCK) {
- KMDTrace("UserIO", 3, "StreamWrite blocking %s at %s\n",
- PPPOID(currentSSP->processOID), PPSSPlace(currentSSP));
- req->vectorWrite = vector;
- req->lengthWrite = length;
- req->waitingWrite = preemptRunning();
- req->waitingWrite->status.rs = SSWriteIOWait;
- KMDTrace("LineNumber", 3, "%s blocking on i/o write in %s\n",
- PPPOID(req->waitingWrite->processOID),
- PPSSPlace(req->waitingWrite));
- SISetSockHandler(req->sock, SIWRITE,
- (SIHandlerPtr) StreamOutputSIGIO);
- return;
- }
- KMDTrace("UserIO", 3, "Write error %d\n", errno);
- perror("StreamWrite");
- /* Should cleanup socket */
- fail(preemptRunning());
- return;
- }
-
- currentSSP->resultBrand = DataBrand;
- currentSSP->regs.arg1 = count;
-
- }
-
- /**********************************************************************/
- /* CloseInStream */
- /**********************************************************************/
- /* Kernel call */
- void CloseInStream(fSock)
- int fSock;
- {
- int i, sock;
- CompilerLoadReqPtr req;
-
- KMDTrace("UserIO", 3, "CloseInStream for sock %d\n", fSock);
- sock = fSock;
-
- if (fSock == fileno(stdin)) {
- KMDTrace("UserIO", 3, "Close on kernel stdin ignored.\n");
- return;
- }
-
- for (i=0; i < 32 && (IsNULL(CReq[i]) || CReq[i]->sock != sock); i++);
-
- if (i == 32) {
- KMDTrace("UserIO", 2, "Close attempt on disconnected socket #%d\n",
- sock);
- return;
- }
-
- req = CReq[i];
- if (IsNULL(currentSSP)) {
- KMDTrace("UserIO", 2, "CloseInStream #%d: Null currentSSP\n", sock);
- } else if (currentSSP->regs.b != req->theInStream) {
- KMDTrace("UserIO", 2,
- "CloseInStream attempt on reconnected socket #%d\n",
- sock);
- return;
- }
-
- req->theInStream = (GODP) NULL;
- if (NonNULL(req->waitingRead)) {
- fail(preemptRunning());
- }
-
- if (req->theOutStream == (GODP) NULL) {
- CReq[i] = (CompilerLoadReqPtr) NULL;
- FreeRequest((GenericReqPtr) req);
- (void) close(sock);
- }
- }
-
- /**********************************************************************/
- /* CloseOutStream */
- /**********************************************************************/
- /* Kernel call */
- void CloseOutStream(fSock)
- int fSock;
- {
- int i, sock;
- CompilerLoadReqPtr req;
-
- KMDTrace("UserIO", 3, "CloseOutStream for sock %d\n", fSock);
-
- sock = fSock;
-
- if (fSock == fileno(stdout)) {
- KMDTrace("UserIO", 3, "Close on kernel stdout ignored.\n");
- return;
- }
-
- for (i=0; i < 32 && (IsNULL(CReq[i]) || CReq[i]->sock != sock); i++);
-
- if (i == 32) {
- KMDTrace("UserIO", 2, "Close attempt on disconnected socket #%d\n",
- sock);
- return;
- }
-
- req = CReq[i];
- if (IsNULL(currentSSP)) {
- KMDTrace("UserIO", 2, "CloseOutStream #%d: Null currentSSP\n", sock);
- } else if (currentSSP->regs.b != req->theOutStream) {
- KMDTrace("UserIO", 2,
- "CloseOutStream attempt on reconnected socket #%d\n",
- sock);
- return;
- }
-
- req->theOutStream = (GODP) NULL;
- if (NonNULL(req->waitingRead)) {
- fail(preemptRunning());
- }
-
- if (req->theInStream == (GODP) NULL) {
- CReq[i] = (CompilerLoadReqPtr) NULL;
- FreeRequest((GenericReqPtr) req);
- (void) close(sock);
- }
- }
- /**********************************************************************/
- /**********************************************************************/
- void GetCodeLoadRootSet(fRootSet)
- Set fRootSet;
- {
- }
-
- /**********************************************************************/
- /**********************************************************************/
-
- /**********************************************************************/
- /* FLSendCode */
- /**********************************************************************/
-
- /* Snapshot for testing the sending of code to someone */
- /* Snapshot */
- void FLSendCode(fLNN, fOID)
- int fLNN;
- char *fOID;
- /* Send the Code given by OID to the node given by fLNN */
- /* Note: OID is represented as ASCII */
- {
- CodeODP theCodeODP;
- OID theCodeOID;
- LMHandle myLMHandle;
- CodeTransferItem item;
- HOTSRecord *hotsPtr;
- DotoFilePtr dotoptr;
-
- if (sscanf(fOID, "%x", &theCodeOID) != 1) {
- KMDPrint("Bad OID\n");
- return;
- }
-
- theCodeODP = (CodeODP) OTLookup(theCodeOID);
- KMDTrace("Code", 3, "Sending Code 0x%08x to host %d\n", theCodeOID, fLNN);
- if ((theCodeODP == NULL) || (theCodeODP->tag.tag != CodeODTag)) {
- KMDPrint("FLSendCode: no such code OID 0x%08x\n", theCodeOID);
- return;
- }
- if ((!mSUCCESS(HOTSSearchPtr(fLNN, &hotsPtr))) || (hotsPtr->NodeStat !=
- Alive) && (hotsPtr->NodeStat != Booting)) {
- KMDPrint("Node %d down.\n", fLNN);
- return;
- }
- dotoptr = (DotoFilePtr)
- addOffset(theCodeODP->dataPtr, -sizeof(dotoptr->header));
- LMStartMsg(&myLMHandle, KMSG_EmKernel, EMKM_FLAcceptCode, fLNN);
- item.hdr.itemTag = CodeTransferITag;
- item.hdr.size = N_STROFF(dotoptr->header) +
- ( * ( (int *)addOffset(dotoptr, N_STROFF(dotoptr->header) ) ) ) +
- sizeof(ItemHdr);
- LMPutData(&myLMHandle, &item, sizeof(item));
- LMPutData(&myLMHandle, dotoptr, item.hdr.size - sizeof(item));
- if (!mSUCCESS(LMSendMsg(&myLMHandle))) {
- KMDPrint("Could not send msg to host %d\n", fLNN);
- }
- }
-
- /**********************************************************************/
- /* FLCodeLoadMap */
- /**********************************************************************/
-
- /*Snapshot*/
- void FLCodeLoadMap()
- {
- CodeLoadReqPtr req;
- OID theOID;
- KMDPrint("CodeLoadMap dump for node #%d\n", GetLNN());
- if (Map_Count(CodeLoadMap) == 0) {
- KMDPrint("No outstanding code load requests.\n");
- return;
- }
- KMDPrint("Code OID \tStatus\n");
- Map_For(CodeLoadMap, theOID, req);
- KMDPrint("C%08x\t%s\n", theOID,
- req->status == DoNotKnow ? "Location unknown" :
- req->status == FoundSomewhere ? "Located" :
- req->status == LoadRequested ? "Code load in progress" :
- req->status == Transferred ? "Code transferred to here" :
- req->status == Translated ? "Code load done":
- "BAD STATUS");
- Map_Next
- }
-
- /**********************************************************************/
- /* FLRemoteLoadMap */
- /**********************************************************************/
-
- /*Snapshot*/
- void FLRemoteLoadMap()
- {
- CodeLoadReqPtr req;
- OID theOID;
- KMDPrint("RemoteLoadMap dump for node #%d\n", GetLNN());
- if (Map_Count(CodeLoadMap) == 0) {
- KMDPrint("No outstanding code load requests.\n");
- return;
- }
- KMDPrint("Code OID \tStatus\n");
- Map_For(RemoteLoadMap, theOID, req);
- KMDPrint("C%08x\t%s\n", theOID,
- req->status == DoNotKnow ? "Location unknown" :
- req->status == FoundSomewhere ? "Located" :
- req->status == LoadRequested ? "Code load in progress" :
- req->status == Transferred ? "Code transferred to here" :
- req->status == Translated ? "Code load done":
- "BAD STATUS");
- Map_Next
- }
-
- /**********************************************************************/
- /* FLCompilerLoadMap */
- /**********************************************************************/
-
- /*Snapshot*/
- void FLCompilerLoadMap()
- {
- CompilerLoadReqPtr req;
- int dummy;
-
- KMDPrint("CompilerLoadMap dump for node #%d\n", GetLNN());
- if (Map_Count(CompilerLoadMap) == 0) {
- KMDPrint("No outstanding code load requests.\n");
- return;
- }
- KMDPrint("Compiler OID \tStatus\n");
- Map_For(CompilerLoadMap, req, dummy);
- KMDPrint("C%08x\t%s\tone of %s\n", req->createdCTOID,
- req->status == Connected ? "Connected" :
- req->status == Loading ? "Loading" :
- req->status == Translating ? "Loaded" :
- "BAD STATUS", PPCOID(req->createdCTOID));
- if (req->status == Translating) {
- if (NonNULL(req->waitingRead)) {
- KMDPrint("\t\t%s blocked on read at %s\n",
- PPPOID(req->waitingRead->processOID),
- PPSSPlace(req->waitingRead));
- }
- if (NonNULL(req->waitingWrite)) {
- KMDPrint("\t\t%s blocked on write at %s\n",
- PPPOID(req->waitingWrite->processOID),
- PPSSPlace(req->waitingWrite));
- }
- }
- Map_Next
- }
-
- /**********************************************************************/
- /* FLCheatingLoadMap */
- /**********************************************************************/
-
- /*Snapshot*/
- void FLCheatingLoadMap()
- {
- CheatingLoadReqPtr req;
- OID theOID;
- KMDPrint("CheatingLoadMap dump for node #%d\n", GetLNN());
- if (Map_Count(CheatingLoadMap) == 0) {
- KMDPrint("No outstanding code load requests.\n");
- return;
- }
- KMDPrint("Code OID \tStatus\n");
- Map_For(CheatingLoadMap, theOID, req);
- KMDPrint("C%08x\t%s\n", theOID,
- req->status == DoNotKnow ? "Unknown" :
- req->status == FoundSomewhere ? "Located" :
- req->status == LoadRequested ? "Code load in progress" :
- req->status == Transferred ? "Code transferred to here" :
- req->status == Translated ? "Code load done":
- "BAD STATUS");
- Map_Next
- }
-
- /**********************************************************************/
- /* FLUnknownATAbConMap */
- /**********************************************************************/
-
- /*Snapshot*/
- void FLUnknownATAbConMap()
- {
- Set theSet;
- OID theATOID;
- AbConPtr theAbConPtr;
-
- KMDPrint("UnknownATAbConMap dump for node #%d\n", GetLNN());
- if (Map_Count(UnknownATAbConMap) == 0) {
- KMDPrint("No AbCons with non-resident ATs.\n");
- return;
- }
- KMDPrint("AT OID \tCT OID\n");
- Map_For(UnknownATAbConMap, theATOID, theSet);
- KMDPrint("%s\n", PPCOID(theATOID));
- Set_For(theSet, theAbConPtr);
- KMDPrint("\t%s\n", PPCOID(theAbConPtr->CodeOID));
- Set_Next
- Map_Next
- }
-
- /**********************************************************************/
- /* FLUnknownATAbConMap */
- /**********************************************************************/
-
- /*Snapshot*/
- void FLAbConMap96()
- {
- OID theATOID, theRestrictOID, theCTOID;
- AbConPtr theAbConPtr;
-
- KMDPrint("AbConMap96 dump for node #%d\n", GetLNN());
- if (Map_Count(AbConMap96) == 0) {
- KMDPrint("No AbCons.\n");
- return;
- }
- Map96_For(AbConMap96, theATOID, theRestrictOID, theCTOID, theAbConPtr);
- KMDPrint("Abcon @ 0x%06x\n:", theAbConPtr);
- KMDPrint("\tAT:\t%s\n", PPCOID(theATOID));
- KMDPrint("\trAT:\t%s\n", PPCOID(theRestrictOID));
- KMDPrint("\tCT:\t%s\n", PPCOID(theCTOID));
- Map96_Next
- }
-
- /**********************************************************************/
- /* FLInit */
- /**********************************************************************/
-
- void FLInit(fPort)
- int fPort;
- {
- register int i;
- KMDSetSnap(FLLoadFile);
- KMDSetSnap(FLSendCode);
- KMDSetSnap(FLCreateOneOfCTOID);
- KMDSetSnap(FLCodeLoadMap);
- KMDSetSnap(FLCompilerLoadMap);
- KMDSetSnap(FLCheatingLoadMap);
- KMDSetSnap(FLRemoteLoadMap);
- KMDSetSnap(FLUnknownATAbConMap);
- KMDSetSnap(FLAbConMap96);
-
- KMDSetTrace(AbCon);
- KMDSetTrace(View);
- KMDSetTrace(Code);
- KMDSetTrace(Translate);
- KMDSetTrace(UserIO);
-
- KMDTrace("Code", 3, "File Load Init, port no = %d.\n", ntohs(fPort));
- CompilerSock = socket(AF_INET, SOCK_STREAM, 0);
- if (CompilerSock < 0) {
- perror("FLInit: socket");
- abort();
- };
- compilerSocket.sin_port = fPort;
- if (bind(CompilerSock, &compilerSocket, sizeof(compilerSocket)) < 0) {
- perror("FLInit: bind(CompilerSock)");
- if (errno == EADDRINUSE) {
- int retry;
- /* The socket is already in use -- wait for it to
- get unbound. UNIX does this after a certain time has
- elapsed -- if a new kernel is rebooted right after
- a previous one has crashed, the bind may fail so
- retry it a number of times */
- for (retry = 1; retry < 20; retry++) {
- printf
- ("Waiting %d seconds for UNIX to clean up previous bind.\n",
- retry*retry);
- sleep ((unsigned) retry*retry);
- if (bind(CompilerSock, &compilerSocket,
- sizeof(compilerSocket)) < 0)
- {
- perror("FLInit: bind retry");
- if (errno != EADDRINUSE) break;
- } else goto ok;
- }
- }
- abort();
- }
-
- ok:
- if (fcntl(CompilerSock, F_SETFL, FASYNC | FNDELAY ) < 0) {
- perror("FLInit: first fcntl");
- abort();
- };
- if (fcntl(CompilerSock, F_SETOWN, getpid()) < 0) {
- perror("FLInit: second fcntl");
- abort();
- };
- #ifdef SO_DONTLINGER
- setsockopt(CompilerSock, SOL_SOCKET, SO_DONTLINGER, 0, 0);
- #endif
-
- check(listen(CompilerSock, 5));
-
- for (i = 0; i < MAXSOCK; i++) CReq[i] = (CompilerLoadReqPtr) NULL;
-
- SISetSockHandler(CompilerSock, SIREAD, (SIHandlerPtr) FLNewRequest);
- SISetSockHandler(CompilerSock, SIEXCEPT,
- (SIHandlerPtr) FLCompilerSockDead);
-
- MMDefineMsgHandler(KMSG_EmKernel, EMKM_FLAcceptCode, AcceptCode, NULL);
-
- SetItemHandler(RemoteLoadReqITag, RemoteLoadItemHandler);
-
- CodeLoadMap = Map_Create();
- CompilerLoadMap = Map_Create();
- CheatingLoadMap = Map_Create();
- RemoteLoadMap = Map_Create();
- UnknownATAbConMap = Map_Create();
- AbConMap96 = Map96_CreateSized(INITIALABCONMAP96SIZE);
- KMDTrace("AbCon", 5, "InitialAbConMap96 size: %d\n",
- INITIALABCONMAP96SIZE);
- }
-